Sixty years since Silent Spring: A systematic review map and bibliometric analysis provides a holistic view of organochlorine pesticide impacts

Kyle Morrison, Coralie Williams, Lorenzo Ricolfi, Yefeng Yang, Malgorazata Lagisz, Shinichi Nakagawa

2023-03-09

In this Rmarkdown document we provide the following workflow:

  • Objective 0 - To examine the volume and temporal trends of existing meta-analyses on the effects of organochlorine pesticides

  • Objective 1: To evaluate the methodological patterns and quality of existing meta-analyses studying the effects of organochlorine pesticides.

  • Objective 2 . To explore the various characteristics of the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

  • Objective 4 - To investigate the research outputs across different countries, continents and disciplines, and investigate the degree of cross-country collaboration.

Load packages and data

Load packages

rm(list = ls())
pacman::p_load(tidyverse,
hrbrthemes, 
patchwork,
here,
stringr,
knitr,
formatR,
forcats,
ggplot2,
bibliometrix,
igraph,
stringi,
stringdist,
circlize,
ggalluvial,
ggraph)
knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE)

Load data

Manually extracted pilot data is stored in five separate .csv files representing different aspects of the data (extracted via structured predefined Google Forms - one per table). Bibliographic data records are exported from Scopus (including cited references field) in .bib format and locally saved as bib_sco.bib.

# Load CSV datasets
sd <- read_csv(here("data", "ocp_srm_study_details.csv"))
ocp <- read_csv(here("data", "ocp_srm_ocp_details.csv"))
sub <- read_csv(here("data", "ocp_srm_subject_details.csv"))
im <- read_csv(here("data", "ocp_srm_impact_details.csv"))
sp <- read_csv(here("data", "ocp_srm_species_details.csv"))

# Load BibTeX dataset
bib_sco <- convert2df(here("data", "bib_sco.bib"), dbsource = "scopus", format = "bibtex")

Objective 1

To evaluate the methodological patterns and quality of existing meta-analyses studying the effects of organochlorine pesticides.

Figure s5

Bar plot showing the percentage and total count of scientific literature databases used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved multiple scientific literature databases. The “Other databases” category includes all databases with a count of 3 or less.

# Calculate the total count for each category
database_count <- sd %>% 
  separate_rows(database_search, sep = ",\\s+") %>% 
  count(database_search) %>% 
  filter(database_search != "not reported") %>% 
  arrange(desc(n)) %>% 
  mutate(database_search = ifelse(n<= 3, "Other databases", as.character(database_search))) %>% 
    group_by(database_search) %>%
  summarise(n = sum(n))


# Calculate proportion and percentage for each category
database_pct <- database_count %>%
  mutate(proportion = n / sum(database_count$n),
         percentage = proportion * 100)

# Create a standard theme for the supplement plots
theme_suppl <- function() {
  theme_minimal() +
  theme(
    axis.text.y = element_text(size = 15),
    axis.text.x = element_text(size = 15),
    axis.line.x = element_line(color = "gray", size = 0.5),
    axis.line.y = element_blank(),
    axis.ticks.x = element_blank(),
    axis.ticks.y = element_blank(),
    axis.title.x = element_text(size = 20),
    axis.title.y = element_text(size = 20),
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    legend.position = "none"
  )
}

# Create the count plot
figs5 <- database_count %>%
  ggplot(aes(x = n, y = reorder(database_search, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(database_search, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = database_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(database_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs5

# ggsave(here("figures", "figs5.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs5.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s6

Alluvial plot showing the relationship between the Journal Citation Report Category and the scientific literature database used. Filtered for scientific literature database counts greater than or equal to 3.

# Rename Environmental Science
sd <- sd %>%
  mutate(Journal_Category_Allocated_Broad = str_replace(Journal_Category_Allocated_Broad, "Environmental Science", "Environmental\nScience"))

# Data Transformation 
database_alluvial <- sd %>% 
    separate_rows(database_search, sep = ",\\s+") %>%
    group_by(Journal_Category_Allocated_Broad, database_search) %>% 
    count(database_search, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(database_search) %>% 
    filter(sum(freq) >= 3) %>% 
    filter(database_search != "NA")

# Create the Alluvial plot
figs6 <- database_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = database_search)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Database Search"), expand = c(.05, .05)) +
  xlab("Variables") +
  ylab("Frequency") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4.5, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs6

# ggsave(here("figures", "figs6.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs6.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s7

Bar plot showing the percentage and total count of effect size calculation types used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved multiple effect size calculations. The “Other effect sizes” category includes all effect sizes with a count of 2 or less.

# Calculate the total count for each category
effectsize_count <- sd %>% 
  separate_rows(effect_size, sep = ",\\s+") %>% 
  count(effect_size) %>%
  filter(effect_size != "NA") %>%
  mutate(effect_size = ifelse(n<= 2, "other effect sizes", as.character(effect_size))) %>% 
  group_by(effect_size) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
effectsize_pct <- effectsize_count %>%
  mutate(proportion = n / sum(effectsize_count$n),
         percentage = proportion * 100)

# Create the count plot
figs7 <-  effectsize_count %>%
  ggplot(aes(x = n, y = reorder(effect_size, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(effect_size, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = effectsize_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(effectsize_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs7

#  ggsave(here("figures", "figs7.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
#  ggsave(here("figures", "figs7.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s8

Alluvial plot showing the relationship between the Journal Citation Report Category and the effect size used. Filtered for scientific literature database counts greater than or equal to 3.

# Data Transformation 
effectsize_alluvial <- sd %>% 
    separate_rows(effect_size, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
    filter(!grepl("no category found", Journal_Category_Allocated_Broad, ignore.case = TRUE)) %>% 
    filter(!is.na(effect_size)) %>%
    group_by(Journal_Category_Allocated_Broad, effect_size) %>% 
    count(effect_size, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(effect_size) 


# Create the Alluvial plot
figs8 <- effectsize_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = effect_size)) +
  scale_x_discrete(limits = c("Journal Category", "Effect Size"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/2.5, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 5) +
  theme_minimal() +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()
  
figs8

# ggsave(here("figures", "figs8.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs8.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s9

Bar plot showing the percentage and total count of software for analysis used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved multiple software.

# Calculate the total count for each category
software_count <- sd %>%
  separate_rows(software_analysis, sep = ",\\s+") %>%
  mutate(software_analysis = ifelse(grepl("comprehensive meta-analysis", software_analysis), "CMAS", software_analysis)) %>%
  mutate(software_analysis = ifelse(grepl("not reported", software_analysis), "no software reported", software_analysis))  %>% 
  count(software_analysis) %>%
  filter(software_analysis != "NA") %>%
  group_by(software_analysis) %>%
  summarise(n = sum(n))


# Calculate proportion and percentage for each category
software_pct <- software_count %>%
  mutate(proportion = n / sum(software_count$n),
         percentage = proportion * 100)

# Create the count plot
figs9 <- software_count %>%
  ggplot(aes(x = n, y = reorder(software_analysis, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(software_analysis, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = software_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(software_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs9

# ggsave(here("figures", "figs9.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs9.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s10

Alluvial plot showing the relationship between the Journal Citation Report Category and the software used for analysis.

# Data Transformation 
software_analysis_alluvial <- sd %>% 
    separate_rows(software_analysis, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
  mutate(software_analysis = ifelse(grepl("comprehensive meta-analysis", software_analysis), "CMAS", software_analysis)) %>%
  mutate(software_analysis = ifelse(grepl("not reported", software_analysis), "no software reported", software_analysis))  %>% 
    filter(!is.na(software_analysis)) %>%
    group_by(Journal_Category_Allocated_Broad, software_analysis) %>% 
    count(software_analysis, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(software_analysis)

# Create the Alluvial plot for Software Analysis
figs10 <- software_analysis_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = software_analysis)) +
  scale_x_discrete(limits = c("Journal Category", "Software Analysis"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs10

# ggsave(here("figures", "figs10.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs10.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s11

Bar plot showing the percentage and total count of heterogeneity assessment methods used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved multiple heterogeneity assessments.

# Calculate the total count for each category
heterogeneity_count <- sd %>% 
  separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>% 
  count(heterogeneity_assessment_method) %>%
    mutate(heterogeneity_assessment_method = ifelse(grepl("not reported", heterogeneity_assessment_method), "no heterogeneity\nmeasure reported", heterogeneity_assessment_method))  %>% 
  filter(heterogeneity_assessment_method != "NA") %>%
    group_by(heterogeneity_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
heterogeneity_pct <- heterogeneity_count %>%
  mutate(proportion = n / sum(heterogeneity_count$n),
         percentage = proportion * 100)

# Create the count plot
figs11 <- heterogeneity_count %>%
  ggplot(aes(x = n, y = reorder(heterogeneity_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(heterogeneity_assessment_method, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = heterogeneity_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(heterogeneity_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs11

# ggsave(here("figures", "figs11.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs11.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s12

Alluvial plot showing the relationship between the Journal Citation Report Category and heterogeneity assessment method.

# Data Transformation 
heterogeneity_alluvial <- sd %>% 
    separate_rows(heterogeneity_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
  mutate(heterogeneity_assessment_method = ifelse(grepl("not reported", heterogeneity_assessment_method), "no heterogeneity\nmeasure reported", heterogeneity_assessment_method))  %>% 
    filter(!is.na(heterogeneity_assessment_method)) %>%
    group_by(Journal_Category_Allocated_Broad, heterogeneity_assessment_method) %>% 
    count(heterogeneity_assessment_method, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(heterogeneity_assessment_method) 

# Create the Alluvial plot
figs12 <- heterogeneity_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = heterogeneity_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Heterogeneity"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4.5, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs12

# ggsave(here("figures", "figs12.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs12.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s13

Bar plot showing the percentage and total count of sensitivity analyses conducted in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved multiple sensitivity analyses.

# Calculate the total count for each category
sensitivity_count <- sd %>% 
  separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>% 
  count(sensitivity_analysis_method) %>%
  filter(sensitivity_analysis_method != "NA") %>%   
  group_by(sensitivity_analysis_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
sensitivity_pct <- sensitivity_count %>%
  mutate(proportion = n / sum(sensitivity_count$n),
         percentage = proportion * 100)

# Create the count plot
figs13 <- sensitivity_count %>%
  ggplot(aes(x = n, y = reorder(sensitivity_analysis_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(sensitivity_analysis_method, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = sensitivity_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(sensitivity_count$n)*1.1)) +
  labs(y = NULL) +
 theme_suppl()

figs13

# ggsave(here("figures", "figs13.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs13.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s14

Alluvial plot showing the relationship between the Journal Citation Report Category and sensitivity analysis.

# Data Transformation 
sensitivity_analysis_alluvial <- sd %>% 
    separate_rows(sensitivity_analysis_method, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
    filter(!is.na(sensitivity_analysis_method)) %>%
    group_by(Journal_Category_Allocated_Broad, sensitivity_analysis_method) %>% 
    count(sensitivity_analysis_method, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(sensitivity_analysis_method)

# Create the Alluvial plot
figs14 <- sensitivity_analysis_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = sensitivity_analysis_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Sensitivity Analysis Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 5) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs14

# ggsave(here("figures", "figs14.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs14.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s15

Bar plot showing the percentage and total count of bias types assessed in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the assessment of multiple bias types.

# Calculate the total count for each category
bias_type_count <- sd %>% 
  separate_rows(bias_assessment_type, sep = ",\\s+") %>% 
  count(bias_assessment_type) %>%
   filter(bias_assessment_type != "NA") %>%
  group_by(bias_assessment_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_type_pct <- bias_type_count %>%
  mutate(proportion = n / sum(bias_type_count$n),
         percentage = proportion * 100)

# Create the count plot
figs15 <- bias_type_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_type, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(bias_assessment_type, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = bias_type_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(bias_type_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs15

# ggsave(here("figures", "figs15.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs15.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s16

Alluvial plot showing the relationship between the Journal Citation Report Category and bias assessment method

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_type, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
    filter(!is.na(bias_assessment_type)) %>%
    group_by(Journal_Category_Allocated_Broad, bias_assessment_type) %>% 
    count(bias_assessment_type, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_type)

# Create the Alluvial plot
figs16 <- bias_assessment_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = bias_assessment_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs16

# ggsave(here("figures", "figs16.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs16.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s17

Bar plot showing the percentage and total count of bias methodologies used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the use of multiple bias assessment methodologies.

# Calculate the total count for each category
bias_method_count <- sd %>% 
  separate_rows(bias_assessment_method, sep = ",\\s+") %>% 
  count(bias_assessment_method) %>%
  filter(bias_assessment_method != "NA") %>%
    group_by(bias_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_method_pct <- bias_method_count %>%
  mutate(proportion = n / sum(bias_method_count$n),
         percentage = proportion * 100)

# Create the count plot
figs17 <- bias_method_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(bias_assessment_method, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = bias_method_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(bias_method_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs17

# ggsave(here("figures", "figs17.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs17.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s18

Alluvial plot showing the relationship between the Journal Citation Report Category and bias assessment method.

# Data Transformation 
bias_assessment_alluvial <- sd %>% 
    separate_rows(bias_assessment_method, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
    filter(!is.na(bias_assessment_method)) %>%
    group_by(Journal_Category_Allocated_Broad, bias_assessment_method) %>% 
    count(bias_assessment_method, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_method)

# Create the Alluvial plot
figs18 <- bias_assessment_alluvial %>% 
  ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = bias_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/3.5, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs18

# ggsave(here("figures", "figs18.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs18.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s19

Bar plot showing the percentage and total count of bias visualizations used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the use of multiple bias visualizations.

# Calculate the total count for each category
bias_visualization_count <- sd %>% 
  separate_rows(bias_assessment_visualization, sep = ",\\s+") %>% 
  count(bias_assessment_visualization) %>%
  filter(bias_assessment_visualization != "NA") %>%
    group_by(bias_assessment_visualization) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
bias_visualization_pct <- bias_visualization_count %>%
  mutate(proportion = n / sum(bias_visualization_count$n),
         percentage = proportion * 100)

# Create the count plot
figs19 <- bias_visualization_count %>%
  ggplot(aes(x = n, y = reorder(bias_assessment_visualization, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(bias_assessment_visualization, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = bias_visualization_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(bias_visualization_count$n)*1.1)) +
  labs(y = NULL) +
 theme_suppl()

figs19

# ggsave(here("figures", "figs19.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs19.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s20

Alluvial plot showing the relationship between the Journal Citation Report Category and bias visualization method.

# Data Transformation 
bias_vizualisation_alluvial <- sd %>% 
    separate_rows(bias_assessment_visualization, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>% 
    filter(!is.na(bias_assessment_visualization)) %>%
    group_by(Journal_Category_Allocated_Broad, bias_assessment_visualization) %>% 
    count(bias_assessment_visualization, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(bias_assessment_visualization)

# Create the Alluvial plot
figs20 <- bias_vizualisation_alluvial %>% 
  ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = bias_assessment_visualization)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Bias Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs20

# ggsave(here("figures", "figs20.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs20.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s21

Bar plot showing the percentage and total count of risk of bias tests used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the use of multiple risk of bias tests.

# Calculate the total count for each category
rob_method_count <- sd %>% 
  separate_rows(rob_assessment_method, sep = ",\\s+") %>% 
  count(rob_assessment_method) %>%
  filter(rob_assessment_method != "NA") %>%
  group_by(rob_assessment_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
rob_method_pct <- rob_method_count %>%
  mutate(proportion = n / sum(rob_method_count$n),
         percentage = proportion * 100)

# Create the count plot
figs21 <- rob_method_count %>%
  ggplot(aes(x = n, y = reorder(rob_assessment_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(rob_assessment_method, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = rob_method_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(rob_method_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs21

# ggsave(here("figures", "figs21.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs21.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s22

Alluvial plot showing the relationship between the Journal Citation Report Category and risk of bias methodology.

# Data Transformation 
robmethod_alluvial <- sd %>% 
     separate_rows(rob_assessment_method, sep = ",\\s+") %>%
    filter(!is.na(rob_assessment_method)) %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>%
    group_by(Journal_Category_Allocated_Broad, rob_assessment_method) %>% 
    count(rob_assessment_method, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(rob_assessment_method) 


# Create the Alluvial plot
figs22 <- robmethod_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = rob_assessment_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "ROB Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/3, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 5) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs22

# ggsave(here("figures", "figs22.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs22.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s23

Bar plot showing the percentage and total count of visualization methods used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the use of multiple visualization methods.

# Calculate the total count for each category
visualization_count <- sd %>% 
  separate_rows(visualization_method, sep = ",\\s+") %>% 
  count(visualization_method) %>%
  filter(visualization_method != "NA") %>%
    group_by(visualization_method) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
visualization_pct <- visualization_count %>%
  mutate(proportion = n / sum(visualization_count$n),
         percentage = proportion * 100)

# Create the count plot
figs23 <- visualization_count %>%
  ggplot(aes(x = n, y = reorder(visualization_method, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(visualization_method, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = visualization_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(visualization_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs23

# ggsave(here("figures", "figs23.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs23.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s24

Alluvial plot showing the relationship between the Journal Citation Report Category and visualization method.

# Data Transformation 
vizualization_alluvial <- sd %>% 
    separate_rows(visualization_method, sep = ",\\s+") %>%
    filter(!is.na(visualization_method)) %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>%
    group_by(Journal_Category_Allocated_Broad, visualization_method) %>% 
    count(visualization_method, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(visualization_method) 


# Create the Alluvial plot
figs24 <- vizualization_alluvial %>% 
ggplot(aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = visualization_method)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "ROB Assessment Method"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/4, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  theme_suppl()

figs24

# ggsave(here("figures", "figs24.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs24.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s25

Bar plot showing the percentage and total count of reporting guidelines used in meta-analyses investigating the impacts of organochlorine pesticides. Note that some meta-analyses may contribute to multiple sections if the study involved the use of multiple reporting guidelines.

# Calculate the total count for each category
reporting_guide_count <- sd %>% 
  separate_rows(reporting_standards_type, sep = ",\\s+") %>% 
  count(reporting_standards_type) %>%
  filter(reporting_standards_type != "NA") %>%
    group_by(reporting_standards_type) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
reporting_guide_pct <- reporting_guide_count %>%
  mutate(proportion = n / sum(reporting_guide_count$n),
         percentage = proportion * 100)

# Create the count plot
figs25 <- reporting_guide_count %>%
  ggplot(aes(x = n, y = reorder(reporting_standards_type, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(reporting_standards_type, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = reporting_guide_pct, aes(label = paste0("(", round(percentage, 0), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(reporting_guide_count$n)*1.1)) +
  labs(y = NULL) +
  theme_suppl()

figs25

# ggsave(here("figures", "figs25.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs25.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s26

An alluvial plot showing the relationship between the Journal Citation Report Category and reporting guideline used

# Data Transformation 
reporting_standards_alluvial <- sd %>% 
    separate_rows(reporting_standards_type, sep = ",\\s+") %>%
    separate_rows(Journal_Category_Allocated_Broad, sep = "/\\s+") %>%
    filter(!grepl("no category found", Journal_Category_Allocated_Broad, ignore.case = TRUE)) %>% 
    filter(!is.na(reporting_standards_type)) %>%
    group_by(Journal_Category_Allocated_Broad, reporting_standards_type) %>% 
    count(reporting_standards_type, Journal_Category_Allocated_Broad) %>% 
    summarise(freq = n(), .groups = 'drop') %>% 
    group_by(reporting_standards_type)

# Create the Alluvial plot
figs26 <- reporting_standards_alluvial %>% 
ggplot( aes(y = freq ,axis1 = Journal_Category_Allocated_Broad, axis2 = reporting_standards_type)) +
  scale_x_discrete(limits = c("Journal Citation Report Category", "Reporting Standards Type"), expand = c(.05, .05)) +
  xlab("Variables") +
  geom_alluvium(aes(fill = Journal_Category_Allocated_Broad)) +
  geom_stratum(width = 1/3.5, fill = "white", color = "black") +
  labs(x= "Variables", y = "Frequency", fill = "Journal Category Allocated") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 6) +
  theme_suppl()

figs26

# ggsave(here("figures", "figs26.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs26.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure 2

A circular treemap showing the counts of each methodological item in exisitng meta-analysis investigating the impacts of organochlorine pesticides

# Grouping "Medline" and "Pubmed" under "PubMed" and summing the counts
database_count <- database_count %>%
  mutate(database_search = if_else(database_search %in% c("Medline", "Pubmed"), "PubMed", database_search)) %>%
  group_by(database_search) %>%
  summarise(n = sum(n))

# Splitting, grouping, and summing different categories of effect sizes
effectsize_count <- sd %>% 
  separate_rows(effect_size, sep = ",\\s+") %>% 
  count(effect_size) %>%
  filter(effect_size != "NA") %>%
  group_by(effect_size) %>%
  summarise(n = sum(n))

effectsize_count <- effectsize_count %>% 
  mutate(effect_size = if_else(effect_size %in% c("Beta regression coefficient", "correlation coefficient"), "Correlation", effect_size)) %>% 
  mutate(effect_size = if_else(effect_size %in% c("odds ratio", "response ratio", "SMD (standardized mean difference)", "lnPR (log partitioning ratio)", "lnOR (log odds ratio)", "ratio of means", "InRR (log response ratio)"), "Mean diff", effect_size)) %>% 
  mutate(effect_size = if_else(effect_size %in% c("risk ratio"), "2x2", effect_size)) %>% 
  mutate(effect_size = if_else(effect_size %in% c("raw weight", "transfer rate", "geometric mean", "maternal transfer ratio", "standardized mortality rate", "Transfer rate", "z-score", "lnCVR (log coefficient variation ratio)"), "Other ES", effect_size)) %>% 
  group_by(effect_size) %>%
  summarise(n = sum(n))

# Categorizing software as either "Code-based software" or "GUI" and summing the counts
software_count <- software_count %>%
  mutate(software_analysis = if_else(software_analysis %in% c("Stata", "R"), "Code-based", software_analysis)) %>%
  mutate(software_analysis = if_else(software_analysis %in% c("CMAS", "Excel", "RevMan", "SAS", "XLSTAT"), "GUI", software_analysis)) %>% 
  group_by(software_analysis) %>%
  summarise(n = sum(n))

# Grouping heterogeneity assessment methods and summing the counts
heterogeneity_count <- heterogeneity_count %>% 
  mutate(heterogeneity_assessment_method = if_else(heterogeneity_assessment_method %in% c("Tau square"), "I squared", heterogeneity_assessment_method)) %>% 
  mutate(heterogeneity_assessment_method = if_else(heterogeneity_assessment_method %in% c("Chi square"), "Q statistic", heterogeneity_assessment_method)) %>% 
  group_by(heterogeneity_assessment_method) %>%
  summarise(n = sum(n))

# Grouping bias assessment methods with count <= 3 under "Other BA" and summing the counts
bias_method_count <- bias_method_count %>% 
  mutate(bias_assessment_method = if_else(bias_assessment_method %in% c("Egger's regression test", "Fail safe", "Begg's test", "Kendall's tau statistic"),"Bias statistical test", bias_assessment_method)) %>% 
  group_by(bias_assessment_method) %>%
  summarise(n = sum(n))

# Grouping sensitivity analysis methods and summing the counts
sensitivity_count <-  sensitivity_count %>%  
  mutate(sensitivity_analysis_method = ifelse(n<= 8, "Other sensitivity analysis", as.character(sensitivity_analysis_method))) %>% 
  group_by(sensitivity_analysis_method) %>%
  summarise(n = sum(n))

# Grouping risk of bias assessment methods with count <= 3 under "Other ROB" and summing the counts
rob_method_count <-  rob_method_count %>%  
  mutate(rob_assessment_method = ifelse(n<= 3, "Other ROB", as.character(rob_assessment_method))) %>% 
  group_by(rob_assessment_method) %>%
  summarise(n = sum(n))

# Grouping visualization methods with count <= 3 under "Other Viz" and summing the counts
visualization_count <- visualization_count %>% 
  mutate(visualization_method = ifelse(n<= 3, "Other Viz", as.character(visualization_method))) %>% 
  group_by(visualization_method) %>%
  summarise(n = sum(n))

# Grouping reporting standards types with count <= 2 under "Other guideline" and summing the counts
reporting_guide_count <- reporting_guide_count %>% 
  mutate(reporting_standards_type = ifelse(n<= 2, "Other guideline", as.character(reporting_standards_type))) %>% 
  group_by(reporting_standards_type) %>%
  summarise(n = sum(n))

# Grouping bias assessment visualization types and summing the counts
bias_visualization_count <- bias_visualization_count %>% 
  mutate(bias_assessment_visualization = if_else(bias_assessment_visualization %in% c("Doi plot", "Trim and fill", "Funnel plot", "Galbraith plot"), "Bias visualization", bias_assessment_visualization)) %>% 
  group_by(bias_assessment_visualization) %>%
  summarise(n = sum(n))

# Combine the data frames and unite the methodology types
df <- bind_rows(
  database_count %>% mutate(methodology_type = 'Database Search'),
  effectsize_count %>% mutate(methodology_type = 'Effect Size'),
  software_count %>%  mutate(methodology_type = "Software"),
  heterogeneity_count %>% mutate(methodology_type = "Heterogeneity"),
  sensitivity_count %>% mutate(methodology_type = "Sensitivity_Analysis"),
  bias_method_count %>%  mutate(methodology_type = "Bias Assessment"),
  rob_method_count %>% mutate(methodology_type = "Risk  of Bias"), 
 # visualization_count %>% mutate(methodology_type = "Visualization"),
  reporting_guide_count %>%  mutate(methodology_type = "Reporting Guide"),
  bias_visualization_count %>%  mutate(methodology_type = "Bias Assessment")
) %>% 
 unite(methodology_type_specific, 
       database_search, 
       effect_size,  
       software_analysis,
       heterogeneity_assessment_method, 
       sensitivity_analysis_method, 
       bias_assessment_method,
       rob_assessment_method, 
      # visualization_method, 
       reporting_standards_type, 
       bias_assessment_visualization,
       remove = TRUE, na.rm = TRUE)

# Preparing the edges dataframe for creating the graph
edges <- df %>%
  rename(from = methodology_type, to = methodology_type_specific, size = n) %>%
  select(c(from,to,size)) %>%
  as.data.frame()

# Preparing the vertices dataframe for creating the graph
vertices <- df  %>%
  rename(name = methodology_type_specific, size = n) %>%
  select(c(name,size)) %>%
  as.data.frame()

# Appending unique 'from' values to vertices and their corresponding summed sizes
vertices[(nrow(edges)+1):(nrow(edges)+length(unique(edges$from))),1] <- unique(edges$from)
N <- aggregate(edges$size, list(edges$from), FUN=sum)
vertices[(nrow(edges)+1):(nrow(edges)+length(unique(edges$from))),2] <- N$x

# Creating a graph object from the edges and vertices dataframes
mygraph <- graph_from_data_frame(edges, vertices = vertices)

# Plotting the graph using a 'circlepack' layout, adding labels and adjusting aesthetics

fig2 <- ggraph(mygraph, layout = 'circlepack', weight = size) + 
    geom_node_circle(aes(fill = as.factor(depth)), color = NA) +
    scale_fill_manual(values = c("#1b9e77", "#88D1AD")) + 
    geom_node_text(aes(label = name, filter = leaf, size = 10), vjust = -0.3, fontface = "bold") +
    geom_node_text(aes(label = paste0("(", size, ")"), filter = leaf, size = 10), vjust = 1, fontface = "bold") +
    theme_void() +
    theme(legend.position = "none") 

fig2

 ggsave(here("figures", "fig2.pdf"), width = 18, height = 15, units = "cm", scale = 2, dpi = 800)
 ggsave(here("figures", "fig2.jpg"), width = 18, height = 15, units = "cm", scale = 2, dpi = 800)

Figure 3

The average reporting quality and rigour of meta-analysis according to CEESAT 2.1 (Woodcock et al., 2014). Gold is regard as the highest score, green is second highest score, amber is second-lowest score, and red is the lowest score. All CEESAT 2.1 items along with our interpretation are provided in the Supplementary File 2.

# Start the data manipulation
percent_ceesat_score <- sd %>%
  filter(!is.na(author_year)) %>%
  select(studies = author_year, starts_with("CEE")) %>%
  na.omit() %>%
  pivot_longer(cols = -studies, names_to = "question", values_to = "score") %>%
  group_by(question, score) %>%
  summarise(n = n(), .groups = 'drop') %>%
  mutate(percent = (n/sum(n))*100, 
         across(c(question, score), as.factor),
         question = fct_recode(question, 
           `1.1 Are the elements of the review question clear?` = "CEESAT2_1.1",
           `2.1 Is there an a-priori method protocol document?` = "CEESAT2_2.1",
           `3.1. Is the approach to searching clearly definedsystematic and\ntransparent?` = "CEESAT2_3.1",
           `3.2. Is the search comprehensive?` = "CEESAT2_3.2",
           `4.1. Are eligibility criteria clearly defined?` = "CEESAT2_4.1",
           `4.2. Are eligibility criteria consistently applied to all potentially relevant\narticles and studies found during the search?` = "CEESAT2_4.2",
           `4.3. Are eligibility decisions transparently reported?` = "CEESAT2_4.3",
           `5.1. Does the review critically appraise each study?` = "CEESAT2_5.1",
           `5.2. During critical appraisal was an effort made to minimise\nsubjectivity?` = "CEESAT2_5.2",
           `6.1. Is the method of data extraction fully documented?` = "CEESAT2_6.1",
           `6.2. Are the extracted data reported for each study?` = "CEESAT2_6.2",
           `6.3. Were extracted data cross checked by more than one reviewer?` = "CEESAT2_6.3",
           `7.1. Is the choice of synthesis approach appropriate?` = "CEESAT2_7.1",
           `7.2. Is a statistical estimate of pooled effect provided together with\nmeasure of variance and heterogeneity among studies?` = "CEESAT2_7.2",
           `7.3 Is variability in the study findings investigated and discussed?` = "CEESAT2_7.3",
           `8.1 Have the authors considered limitations in the synthesis?` = "CEESAT2_8.1"),
         question = factor(question, levels = rev(levels(question))),
         score = factor(score, levels = levels(score)[c(4,1,3,2)]))

# Create CEESAT plot 
fig3 <- ggplot(data = percent_ceesat_score, aes(x = question, y = percent, fill = score)) +
  geom_col(width = 0.7, position = "fill", color = "black") +
  geom_text(aes(label = n), position = position_fill(vjust = 0.5), size = 7, fontface = "bold") +
  coord_flip() +
  guides(fill = guide_legend(reverse = TRUE)) +
  scale_fill_manual(values = c("#FF0000","#FFD700","#008000", "#DAA520"), name = "Score:") +
  scale_y_continuous(labels = scales::percent) +
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        panel.background = element_blank(),
        axis.text.y = element_text(size = 20),
        axis.text.x = element_text(size = 20),
        axis.title.x = element_text(size = 25),
        axis.title.y = element_text(size = 25), 
          legend.position = "none") +
  ylab("Percentage") + 
  xlab("CEESAT Question")

fig3

# ggsave(here("figures", "fig3.pdf"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "fig3.jpg"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)

Objective 2

To explore the various characteristics of the organochlorine pesticides literature such as the pesticides used, the impacts elicited in response and the subjects that were investigated.

Figure s27

A bar plot showing the percentage and total count of total of pesticides investigate in meta-analysis investigating the impacts of organochlorine pesticides. Note: some meta-analysis may contribute to multiple sections if the study involves multiple organochlorine pesticides. Filtered for pesticide counts greater than 6.

# Function to replace long OCP names with abbreviations
replace_ocp <- function(df) {
  df %>% 
    mutate(ocp = case_when(
      # HCH related replacements
      grepl("Hexachlorocyclohexane \\(HCH\\)", ocp, ignore.case = TRUE) ~ "HCH",
      grepl("alpha-Hexachlorocyclohexane \\(alpha-HCH\\)", ocp, ignore.case = TRUE) ~ "α - HCH",
      grepl("beta-Hexachlorocyclohexane \\(beta-HCH\\)", ocp, ignore.case = TRUE) ~ "β - HCH",
      grepl("gamma-Hexachlorocyclohexane \\(gamma-HCH\\)", ocp, ignore.case = TRUE) ~ "Lindane",
      # DDT related replacements
      grepl("Dichlorodiphenyltrichloroethane \\(DDT\\)", ocp, ignore.case = TRUE) ~ "DDT",
      grepl("p,p-Dichlorodiphenyltrichloroethane \\(p,p-DDT\\)", ocp, ignore.case = TRUE) ~ "p,p-DDT",
      grepl("o,p-Dichlorodiphenyltrichloroethane \\(o,p-DDT\\)", ocp, ignore.case = TRUE) ~ "o,p-DDT",
      # DDD related replacements
      grepl("Dichlorodiphenyldichloroethane \\(DDD\\)", ocp, ignore.case = TRUE) ~ "DDD",
      grepl("p,p-Dichlorodiphenyldichloroethane \\(p,p-DDD\\)", ocp, ignore.case = TRUE) ~ "p,p-DDD",
      grepl("o,p-Dichlorodiphenyldichloroethane \\(o,p-DDD\\)", ocp, ignore.case = TRUE) ~ "o,p-DDD",
      # DDE related replacements
      grepl("Dichlorodiphenyldichloroethylene \\(DDE\\)", ocp, ignore.case = TRUE) ~ "DDE",
      grepl("p,p-Dichlorodiphenyldichloroethylene \\(p,p-DDE\\)", ocp, ignore.case = TRUE) ~ "p,p-DDE",
      grepl("o,p-Dichlorodiphenyldichloroethylene \\(o,p-DDE\\)", ocp, ignore.case = TRUE) ~ "o,p-DDE",
      TRUE ~ ocp  # no change for any others
    ))
}
# Transform the data 
ocp_count <-
  ocp %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  replace_ocp %>% 
  count(ocp) %>% 
  filter(!is.na(ocp)) %>% # filter out NA 
  arrange(desc(n)) %>% 
  mutate(ocp = ifelse(n <= 6, "other OCP", as.character(ocp))) %>% 
# Other organochlorine pesticides include: toxaphene (n=6), Methoxychlor (n=6), p,p-DDD (n=5), o,p-DDD (n=5), cis-Chlordane (n=5), trans=Chlordane (n=4), Endosulfan II (n=4), Endosulfan (n=3),o,p-DDD (n=3), cis-Nonachlor (n=3) y-Chlordane (n=2), Chlorophenol (n=2), beta-BHC (n=2), alpha-Chlordane (n=2), TCDD (n=1), Nonachlore (n=1), Endrin ketone (n=1), Endrin Aldehyde (n=1), Endosulfan sulfate (n=1), Dicofol (n=1), delta-HCH (n=1), delta-BHC (n=1), DDD (n=1), cis-Heptachlor (n=1), alpha-BHC (n=1).
  group_by(ocp) %>% 
  summarise(n =sum(n))

# Calculate the proportion and percentage of each OCP
ocp_pct <- ocp_count %>%
  mutate(proportion = n/sum(ocp_count$n),
         percentage = proportion*100)

# Create the count plot for OCPs
figs27 <- ocp_count %>%
  ggplot(aes(x = n, y = reorder(ocp, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8, alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(ocp, n)), hjust = 0.5, size = 6, color = "black") +
  geom_text(data = ocp_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = - 0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(ocp_count$n)*1.2)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 15),
        axis.text.x = element_text(size = 15),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none"
        )

figs27

# ggsave(here("figures", "figs27.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs27.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s28

A bar plot showing the percentage and total count of total of subjects investigate in meta-analysis investigating the impacts of organochlorine pesticides. Note: some meta-analysis may contribute to multiple sections if the study involves multiple subjects

# Calculate total count for each category
subject_count <- 
  sub %>% 
    separate_rows(subject, sep = ",\\s+") %>% 
    count(subject)

# Calculate proportion and percentage for each category
subject_pct <- subject_count %>%
  mutate(proportion = n/sum(subject_count$n),
         percentage = proportion*100)

# Create the count plot for subjects
figs28 <- subject_count %>%
  ggplot(aes(x = n, y = reorder(subject, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(subject, n)), hjust = 0.5, size = 7, color = "black") +
  geom_text(data = subject_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(subject_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 15),
        axis.text.x = element_text(size = 15),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none"
        )

figs28

# ggsave(here("figures", "figs28.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs28.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s29

A bar plot showing the percentage and total count of total of subjects investigate in meta-analysis investigating the impacts of organochlorine pesticides. Note: some meta-analysis may contribute to multiple sections if the study involves multiple subjects. Filtered for impact counts greater than 1.

# Calculate total count for each category
impact_count <- 
  im %>% 
    separate_rows(impact, sep = ",\\s+") %>% 
    count(impact) %>% 
  filter(impact != "NA") %>%
  mutate(impact = ifelse(n<= 1, "other", as.character(impact))) %>% 
    group_by(impact) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
impact_pct <- impact_count %>%
  mutate(proportion = n/sum(impact_count$n),
         percentage = proportion*100)

# Create the count plot for impacts 
figs29 <- impact_count %>%
  ggplot(aes(x = n, y = reorder(impact, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(impact, n)), hjust = 0.5, size = 7, color = "black") +
  geom_text(data = impact_pct, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(impact_count$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 15),
        axis.text.x = element_text(size = 15),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none"
        )

figs29

# ggsave(here("figures", "figs29.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs29.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s30

A bar plot showing the percentage and total count of total of impact categories investigated in meta-analysis investigating the impacts of organochlorine pesticides. Note: some meta-analysis may contribute to multiple sections if the study involves multiple impacts

# Create a collumn for broad impacts
im <- im %>%
        separate_rows(impact, sep = ",\\s+") %>% 
  mutate(impact_broad = case_when(
    impact %in% c("parkinsons disease", "alzheimers disease", "autism spectrum disorder", "brain tumour", "amyotrophic lateral sclerosis" ) ~ "Neurological",
    impact %in% c("concentration", "contamination") ~ "Concentration",
    impact %in% c("diabetes", "thyroid function", "hypertension", "endometriosis") ~ "Endocrine",
    grepl("cancer", impact, ignore.case = TRUE) | impact %in% c("leukemia", "lymphoma", "multiple myeloma", "neuroblastoma") ~ "Carcinogen",
    impact %in% c("respiratory health", "cardiovascular disease", "asthma", "prolonged bradycardia") ~ "Cardiovascular",
 #   impact %in% c("birth outcomes", "birth weight", "preterm birth") ~ "Birth",
    impact %in% c("obesity", "adiposity") ~ "Obesity",
    impact %in% c("sperm quality", "neuroblastoma", "hypospadias", "cryptochidism", "reproductive system") ~ "Reproduction",
    TRUE ~ "Other Impact"
  ))


# Calculate total count for each category
impact_count_broad <- 
  im %>% 
    separate_rows(impact_broad, sep = ",\\s+") %>% 
    count(impact_broad) %>% 
  filter(impact_broad != "NA") %>%
    group_by(impact_broad) %>%
  summarise(n = sum(n))

# Calculate proportion and percentage for each category
impact_pct_broad <- impact_count_broad %>%
  mutate(proportion = n/sum(impact_count_broad$n),
         percentage = proportion*100)


# Create the count plot for impacts 
figs30 <- impact_count_broad %>%
  ggplot(aes(x = n, y = reorder(impact_broad, n), fill = "#1b9e77")) +
  geom_bar(stat = "identity", width = 0.8 , alpha = 0.7) +
  geom_text(aes(label = n, x = n / 2, y = reorder(impact_broad, n)), hjust = 0.5, size = 7, color = "black") +
  geom_text(data = impact_pct_broad, aes(label = paste0("(", round(percentage, 1), "%)"), x = n), 
            hjust = -0.1, size = 6, color = "black", fontface = "bold") +
  scale_fill_identity(guide = "none") +
  scale_x_continuous(name = "Article Count", expand = c(0, 0), limits = c(0, max(impact_count_broad$n)*1.1)) +
  labs(y = NULL) +
  theme_minimal() +
  theme(axis.text.y = element_text(size = 15),
        axis.text.x = element_text(size = 15),
        axis.line.x = element_line(color = "gray", size = 0.5),
        axis.line.y = element_blank(),
        axis.ticks.x = element_blank(),
        axis.ticks.y = element_blank(),
        axis.title.x = element_text(size = 20),
        axis.title.y = element_text(size = 20),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        legend.position = "none"
        )

figs30

# ggsave(here("figures", "figs30.pdf"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs30.jpg"), width = 16, height = 10, units = "cm", scale = 2, dpi = 800)

Figure s31

An alluvial plot showing the relationships between the pesticide of exposure, the subject being exposed and the impact of exposure

# Function to change OCP to be more general
replace_ocp2 <- function(df) {
  df %>% 
  mutate(ocp = case_when(
    grepl("Chlordane", ocp, ignore.case = TRUE) ~ "Chlordane",  
    grepl("Endosulfan", ocp, ignore.case = TRUE) ~ "Endosulfan", 
    grepl("Nonachlor", ocp, ignore.case = TRUE) ~ "Nonachlore", 
    grepl("Heptachlor", ocp, ignore.case = TRUE) ~ "Heptachlor",
    grepl("TCDD", ocp, ignore.case = TRUE) ~ "TCDD", 
    grepl("Endrin", ocp, ignore.case = TRUE) ~ "Endrin",
    grepl("Hexachlorobenzene", ocp, ignore.case = TRUE) ~ "HCH",
    grepl("Lindane", ocp, ignore.case = TRUE) ~ "HCH", 
    grepl("Hexachlorocyclohexane \\(HCH\\)", ocp, ignore.case = TRUE) ~ "HCH",
    grepl("alpha-Hexachlorocyclohexane \\(alpha-HCH\\)", ocp, ignore.case = TRUE) ~ "HCH",
    grepl("beta-Hexachlorocyclohexane \\(beta-HCH\\)", ocp, ignore.case = TRUE) ~ "HCH",
    grepl("gamma-Hexachlorocyclohexane \\(gamma-HCH\\)", ocp, ignore.case = TRUE) ~ "HCH",
    grepl("Dichlorodiphenyltrichloroethane \\(DDT\\)", ocp, ignore.case = TRUE) ~ "DDT",
    grepl("p,p-Dichlorodiphenyltrichloroethane \\(p,p-DDT\\)", ocp, ignore.case = TRUE) ~ "DDT",
    grepl("o,p-Dichlorodiphenyltrichloroethane \\(o,p-DDT\\)", ocp, ignore.case = TRUE) ~ "DDT",
    grepl("Dichlorodiphenyldichloroethane \\(DDD\\)", ocp, ignore.case = TRUE) ~ "DDD",
    grepl("p,p-Dichlorodiphenyldichloroethane \\(p,p-DDD\\)", ocp, ignore.case = TRUE) ~ "DDD",
    grepl("o,p-Dichlorodiphenyldichloroethane \\(o,p-DDD\\)", ocp, ignore.case = TRUE) ~ "DDD",
    grepl("Dichlorodiphenyldichloroethylene \\(DDE\\)", ocp, ignore.case = TRUE) ~ "DDE",
    grepl("p,p-Dichlorodiphenyldichloroethylene \\(p,p-DDE\\)", ocp, ignore.case = TRUE) ~ "DDE",
    grepl("o,p-Dichlorodiphenyldichloroethylene \\(o,p-DDE\\)", ocp, ignore.case = TRUE) ~ "DDE",
    TRUE ~ ocp
  ))
}
 
# Transform the data 
alluvial <- im %>%
  left_join(ocp, by = "study_id") %>%
  left_join(sub, by = "study_id") %>%
  separate_rows(subject, sep = ",\\s+") %>% 
  separate_rows(ocp, sep = ",\\s+") %>% 
  separate_rows(impact_broad, sep = ",\\s+") %>%
  replace_ocp2() %>%
  filter(!grepl("not reported", ocp, ignore.case = TRUE)) %>%
  group_by(ocp, subject, impact_broad) %>%
  summarise(freq = n(), .groups = 'drop') %>%
  group_by(ocp) %>%
  filter(sum(freq) > 10) %>%  
  group_by(impact_broad) %>% 
  filter(sum(freq) > 5) %>% 
  mutate(subject = factor(subject, levels = c("Environment", "Non-human animal", "Human"), ordered = TRUE))

# Make alluvial plot
figs31 <- alluvial %>% 
  ggplot(
       aes(axis1 = ocp, axis2 = subject, axis3 = impact_broad, y = freq)) +
  scale_x_discrete(limits = c("Organochlorine Pesticide", "Subject", "Impact"), expand = c(.05, .10)) +
  xlab("Variables") +
  ylab("Frequency") +  
  geom_alluvium(aes(fill = subject)) +
  geom_stratum(width = 1/2, fill = "white", color = "black") +
  geom_text(stat = "stratum", aes(label = after_stat(stratum)), size = 5, fontface = "bold") +  
  theme_minimal() +
  theme(axis.text=element_text(size=15),  
        axis.title=element_text(size=20),
        legend.position="none",
        panel.grid.major = element_blank(),  
        panel.grid.minor = element_blank()  
  ) + 
  scale_fill_brewer(palette = "Dark2", name = "Subject Category")

figs31

# ggsave(here("figures", "figs31.pdf"), width =18, height = 12, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs31.jpg"), width = 18, height = 12, units = "cm", scale = 2, dpi = 800)

Figure 4

A bubble plot showing the counts of each pesticide per impact included in current meta-analysis on the impacts of orhanochlorine pesticides

# Join the organochlorine pesticide details with the impact details
ocp_im <- left_join(ocp, im ,sub, by = "study_id") 

# Separate rows in "ocp_im"
ocp_im1 <- separate_rows(ocp_im, ocp , sep = ", ", convert = TRUE)


# Group by "ocp" and "impact" and summarize count
ocp_im_summary <- ocp_im1 %>%
  mutate(ocp = str_trim(ocp),
         impact_broad = str_trim(impact_broad)) %>%
    replace_ocp2() %>% 
  group_by(ocp, impact_broad) %>%
  summarise(count = n(), .groups = "drop") 


# Filter for top 5 pesticides 
top_pesticides <- ocp_im_summary %>%
  filter(ocp != "not reported") %>%
  group_by(ocp) %>%
  summarise(total_count = sum(count)) %>%
  top_n(8, total_count) %>%
  pull(ocp) 


ocp_im_summary_filtered <- ocp_im_summary %>%
  filter(ocp %in% top_pesticides)

# Create a circle plot with impact on the x-axis and ocp on the y-axis
fig4 <- ocp_im_summary_filtered %>% 
ggplot(aes(x = fct_rev(fct_reorder(impact_broad, count, .fun = 'sum')),
           y = fct_reorder(ocp, count, .fun = 'sum'),
           size = count,
           fill = count)) +
  geom_point(shape = 21, color = "white") +
  geom_text(aes(label = count), size = 8, fontface = "bold") +  
  scale_fill_gradient(low = "#98FB98", high = "#006400") +
  labs(x = "Impact",
       y = "Organochlorine Pesticide",
       fill = "Count") +
  theme_minimal() +
  theme(
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(size = 20),  
        axis.text.y = element_text(size = 20, hjust = 1),  
        axis.title.x = element_text(size = 25),  
        axis.title.y = element_text(size = 25),  
        legend.position = "none") +
  scale_size_continuous(range = c(15, 45)) 

fig4

# ggsave(here("figures", "fig4.pdf"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "fig4.jpg"), width = 25, height = 15, units = "cm", scale = 2, dpi = 800)

Objective 3

To investigate global research output and collaboration networks

Figure s32, s33, s34, s35 & s36

figs32 <- biblioAnalysis(bib_sco)
plot(figs32)

summary(figs32)
## 
## 
## MAIN INFORMATION ABOUT DATA
## 
##  Timespan                              1993 : 2022 
##  Sources (Journals, Books, etc)        45 
##  Documents                             100 
##  Annual Growth Rate %                  9.25 
##  Document Average Age                  7.78 
##  Average citations per doc             58.6 
##  Average citations per year per doc    6.523 
##  References                            7548 
##  
## DOCUMENT TYPES                     
##  article               50 
##  conference paper      2 
##  review                48 
##  
## DOCUMENT CONTENTS
##  Keywords Plus (ID)                    1592 
##  Author's Keywords (DE)                258 
##  
## AUTHORS
##  Authors                               544 
##  Author Appearances                    684 
##  Authors of single-authored docs       1 
##  
## AUTHORS COLLABORATION
##  Single-authored docs                  1 
##  Documents per Author                  0.184 
##  Co-Authors per Doc                    6.84 
##  International co-authorships %        41 
##  
## 
## Annual Scientific Production
## 
##  Year    Articles
##     1993        1
##     1995        1
##     1999        1
##     2000        1
##     2004        2
##     2006        3
##     2007        1
##     2008        2
##     2009        1
##     2010        4
##     2011        3
##     2012        5
##     2013        5
##     2014        9
##     2015        7
##     2016       11
##     2017        4
##     2018        2
##     2019        7
##     2020        8
##     2021        9
##     2022       13
## 
## Annual Percentage Growth Rate 9.25 
## 
## 
## Most Productive Authors
## 
##       Authors        Articles    Authors        Articles Fractionalized
## 1  LISON D                  7 LISON D                             2.000
## 2  VAN MAELE-FABRY G        7 VAN MAELE-FABRY G                   2.000
## 3  BONDE JP                 5 DAVIS WJ                            1.000
## 4  BALLESTER F              4 GAMET-PAYRASTRE L                   0.867
## 5  CHEVRIER C               4 KREWSKI D                           0.867
## 6  EGGESBØ M                4 HOET P                              0.833
## 7  GOVARTS E                4 FU X                                0.750
## 8  SCHOETERS G              4 MUÑOZ CC                            0.750
## 9  TRNOVEC T                4 VERMEIREN P                         0.750
## 10 ZHANG Y                  4 LEVY LS                             0.700
## 
## 
## Top manuscripts per citations
## 
##                                       Paper                                      DOI  TC TCperYear  NTC
## 1  BROWN TP, 2006, ENVIRON HEALTH PERSPECT           10.1289/ehp.8095                329     18.28 1.85
## 2  GOVARTS E, 2012, ENVIRON HEALTH PERSPECT          10.1289/ehp.1103767             228     19.00 1.81
## 3  PEZZOLI G, 2013, NEUROLOGY                        10.1212/WNL.0b013e318294b3c8    207     18.82 2.08
## 4  BONDE JP, 2016, HUM REPROD UPDATE                 10.1093/HUMUPD/DMW036           188     23.50 2.24
## 5  RIGÉT F, 2010, SCI TOTAL ENVIRON                  10.1016/j.scitotenv.2009.07.036 162     11.57 1.50
## 6  VAN DER MARK M, 2012, ENVIRON HEALTH PERSPECT     10.1289/ehp.1103881             161     13.42 1.28
## 7  OJAJÄRVI IA, 2000, OCCUP ENVIRON MED              10.1136/oem.57.5.316            153      6.38 1.00
## 8  SCHINASI L, 2014, INT J ENVIRON RES PUBLIC HEALTH 10.3390/ijerph110404449         148     14.80 2.90
## 9  SONG Y, 2016, J DIABETES                          10.1111/1753-0407.12325         140     17.50 1.67
## 10 ADAMI HO, 1995, CANCER CAUSES CONTROL             10.1007/BF00054165              140      4.83 1.00
## 
## 
## Corresponding Author's Countries
## 
##           Country Articles   Freq SCP MCP MCP_Ratio
## 1  CHINA                17 0.1753  12   5     0.294
## 2  USA                  11 0.1134   9   2     0.182
## 3  BELGIUM               7 0.0722   5   2     0.286
## 4  CANADA                6 0.0619   3   3     0.500
## 5  FRANCE                6 0.0619   2   4     0.667
## 6  BRAZIL                5 0.0515   5   0     0.000
## 7  DENMARK               5 0.0515   0   5     1.000
## 8  SPAIN                 5 0.0515   0   5     1.000
## 9  NETHERLANDS           4 0.0412   3   1     0.250
## 10 UNITED KINGDOM        4 0.0412   3   1     0.250
## 
## 
## SCP: Single Country Publications
## 
## MCP: Multiple Country Publications
## 
## 
## Total Citations per Country
## 
##      Country      Total Citations Average Article Citations
## 1  DENMARK                    687                     137.4
## 2  USA                        686                      62.4
## 3  CHINA                      607                      35.7
## 4  UNITED KINGDOM             567                     141.8
## 5  BELGIUM                    488                      69.7
## 6  CANADA                     417                      69.5
## 7  FRANCE                     389                      64.8
## 8  NETHERLANDS                259                      64.8
## 9  ITALY                      207                     207.0
## 10 SPAIN                      181                      36.2
## 
## 
## Most Relevant Sources
## 
##                                  Sources        Articles
## 1  ENVIRONMENTAL HEALTH PERSPECTIVES                  10
## 2  SCIENCE OF THE TOTAL ENVIRONMENT                    9
## 3  ENVIRONMENT INTERNATIONAL                           7
## 4  CANCER CAUSES AND CONTROL                           5
## 5  ENVIRONMENTAL RESEARCH                              5
## 6  ENVIRONMENTAL SCIENCE AND POLLUTION RESEARCH        5
## 7  ENVIRONMENTAL SCIENCE AND TECHNOLOGY                4
## 8  SCIENTIFIC REPORTS                                  4
## 9  CHEMOSPHERE                                         3
## 10 ENVIRONMENTAL POLLUTION                             3
## 
## 
## Most Relevant Keywords
## 
##    Author Keywords (DE)      Articles Keywords-Plus (ID)     Articles
## 1      META-ANALYSIS               43 ENVIRONMENTAL EXPOSURE       92
## 2      PESTICIDES                  28 HUMAN                        84
## 3      SYSTEMATIC REVIEW           18 PESTICIDE                    79
## 4      OCCUPATIONAL EXPOSURE        8 HUMANS                       71
## 5      DDT                          7 FEMALE                       70
## 6      CHILD                        6 META ANALYSIS                64
## 7      DDE                          5 PESTICIDES                   60
## 8      BREAST CANCER                4 OCCUPATIONAL EXPOSURE        57
## 9      INSECTICIDES                 4 MALE                         56
## 10     ORGANOCHLORINES              4 PRIORITY JOURNAL             53

Figure s37

Thematic map based on keywords extracted from ID field (obtained on the Scopus scientific literature database) of meta-analysis included in the systematic review map.

par(mfrow=c(1,1), mar=c(0,2,0,2))
fig37 <- thematicMap(bib_sco, field = "ID", n = 1500, minfreq = 1, stemming = FALSE, size = 1, n.labels = 1, repel = TRUE)
plot(fig37$map)

Figure 5

Heat map of world showing the country-level counts for first authors’ country of affiliation of meta-analysis investigating the impacts of organochlorine pesticides. Grey indicates no publications affiliated with a given country in our data set.

# Extract country information from the "AU1_CO" and "AU_CO" fields of the "bib_sco" dataset
bibmap <- metaTagExtraction(bib_sco, Field = "AU1_CO", sep = ";") 
bibmap <- metaTagExtraction(bibmap, Field = "AU_CO", sep = ";") 

# Create a data frame with counts of articles from each country
firstcountrycounts <- bibmap %>% 
  group_by(AU1_CO) %>% 
  count() %>% 
  filter(!is.na(AU1_CO))  

# Load world map data and remove countries with longitude >180 to make an equal projection-like map
world_map <- map_data("world") %>% 
  filter(! long > 180)

# Format country names to match regions on the world map
firstcountrycounts$region <- str_to_title(firstcountrycounts$AU1_CO)
firstcountrycounts$region[firstcountrycounts$region == "Usa"] <- "USA" 
firstcountrycounts$region[firstcountrycounts$region == "Korea"] <- "South Korea"
firstcountrycounts$region[firstcountrycounts$region == "United Kingdom"] <- "UK"

# Join count data with map data and set missing counts to zero
emptymap <- tibble(region = unique(world_map$region), n = rep(0,length(unique(world_map$region))))
fullmap <- left_join(emptymap, firstcountrycounts, by = "region")
fullmap$n <- fullmap$n.x + fullmap$n.y
fullmap$n[is.na(fullmap$n)] <- 0

fig5 <- fullmap %>%
  ggplot(aes(fill = n, map_id = region)) +
  geom_map(map = world_map, color = "gray50") +
  expand_limits(x = world_map$long, y = world_map$lat) +
  coord_map("mercator") +
  theme_minimal() +
  theme(
    axis.text = element_blank(),  
    axis.title = element_blank(),  
    legend.position = "bottom",
    legend.box = "horizontal",  
    legend.box.just = "center",  
    legend.margin = margin(t = 10, unit = "pt"),  
    legend.text = element_text(size = 12),  
    legend.title = element_text(size = 14, face = "bold"),  
    legend.key.width = unit(30, "mm")  
  ) +
  scale_fill_gradient(
    low = "#98FB98", high = "#006400",
    name = "Score", na.value = "gray70",
    limits = c(1, 20)) +
  guides(
    fill = guide_colourbar(
      barwidth = unit(180, units = "mm"),
      barheight = unit(3, units = "mm")
    )
  )

fig5

# ggsave(here("figures", "fig5.pdf"), width = 21, height = 12, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "fig5.jpg"), width = 21, height = 12, units = "cm", scale = 2, dpi = 800)

Figure s43

Heat map of Europe showing the country-level counts for first authors’ country of affiliation of meta-analysis investigating the impacts of organochlorine pesticides. Grey indicates no publications affiliated with a given country in our data set.

figs43 <- fullmap %>%
ggplot(aes(fill = n, map_id = region)) +
geom_map(map = world_map, color = "gray50") +
coord_map("mercator", ylim = c(30, 65), xlim = c(-35, 55)) + 
theme(
    axis.text = element_blank(),  
    axis.title = element_blank(),  
    legend.box = "horizontal",  
    legend.box.just = "center",  
    legend.margin = margin(t = 10, unit = "pt"),  
    legend.text = element_text(size = 12),  
    legend.title = element_text(size = 14, face = "bold"),  
    legend.key.width = unit(30, "mm"),
    legend.position = "bottom"  
  ) +
scale_fill_gradient(low = "#98FB98", high = "#006400",
    name = "Score", na.value = "gray70",
    limits = c(1, 10)) +
guides(fill = guide_colourbar(barwidth = unit(180, units = "mm"), barheight = unit(3, units = "mm")))

figs43

# ggsave(here("figures", "figs43.pdf"), width = 21, height = 12, units = "cm", scale = 2, dpi = 800)
# ggsave(here("figures", "figs43.jpg"), width = 21, height = 12, units = "cm", scale = 2, dpi = 800)

Figure s44

Chord diagram of collaborations across countries. Countries represent the location of the primary authors’ affiliated institution.

# Extract countries from the affiliations
bib_sco2 <- metaTagExtraction(bib_sco, Field = "AU_CO", sep = ";")

# Create a network matrix of collaborations between countries
NetMatrix_country <- biblioNetwork(bib_sco2, analysis = "collaboration", network = "countries", sep = ";")

# Convert the network matrix to a standard matrix
NetMatrix_country <- as.matrix(NetMatrix_country)

# Remove the lower triangle (as this is duplication of info)
NetMatrix_country[lower.tri(NetMatrix_country)] <- 0 

# Change column and row names to title case
colnames(NetMatrix_country) <- str_to_title(colnames(NetMatrix_country))
rownames(NetMatrix_country) <- str_to_title(rownames(NetMatrix_country))

# Change "Usa" to "USA"
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "Usa"] <- "USA"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "Usa"] <- "USA"

# Change "United Kingdom" to "UK" for easier plotting
colnames(NetMatrix_country)[colnames(NetMatrix_country) == "United Kingdom"] <- "UK"
rownames(NetMatrix_country)[rownames(NetMatrix_country) == "United Kingdom"] <- "UK"

# Setting up custom parameters
circos.par(cell.padding = c(0, 0, 0, 0), track.margin = c(0, 0))

# Create a chord diagram of the network matrix
figs44 <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, bg.border = NA, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2 , sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
})

Figure s45

Chord diagram illustration of collaborations across countries. Countries represent the location of the primary authors’ affiliated institution. Collaborations within countries are not shown.

diag(NetMatrix_country) <- 0

# Create a chord diagram of the network matrix
figs45 <- chordDiagram(NetMatrix_country, annotationTrack = "grid", preAllocateTracks = 1)

# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

Figure s46

Chord diagram illustration of collaborations across continents. Continents represent the location of the primary authors’ affiliated institution. Collaborations within countries are not shown.

# Country rename to continents
NetMatrix_continent <- NetMatrix_country
colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "USA"] <- "North\nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "USA"] <- "North\nAmerica"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Spain"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Spain"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "China"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "China"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "France"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "France"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Canada"] <- "North\nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Canada"] <- "North\nAmerica"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Denmark"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Denmark"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Netherlands"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Netherlands"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Belgium"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Belgium"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "UK"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "UK"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Australia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Australia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Brazil"] <- "South America"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Brazil"] <- "South America"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Germany"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Germany"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Finland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Finland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Greece"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Greece"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Korea"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Korea"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Norway"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Norway"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Sweden"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Sweden"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Egypt"] <- "Africa"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Egypt"] <- "Africa"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Italy"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Italy"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Japan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Japan"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Portugal"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Portugal"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Switzerland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Switzerland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Turkey"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Turkey"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "India"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "India"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iran"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iran"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Costa Rica"] <- "North\nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Costa Rica"] <- "North\nAmerica"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Czech Republic"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Czech Republic"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Hong Kong"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Hong Kong"] <- "Asia"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Iceland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Iceland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ireland"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ireland"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Mexico"] <- "North\nAmerica"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Mexico"] <- "North\nAmerica"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Romania"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Romania"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Slovakia"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Slovakia"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Ukraine"] <- "Europe"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Ukraine"] <- "Europe"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Australia"] <- "Oceania"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Australia"] <- "Oceania"

colnames(NetMatrix_continent)[colnames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"
rownames(NetMatrix_continent)[rownames(NetMatrix_continent) == "Kazakhstan"] <- "Asia"


# collapsing
merge_matrix <- t(rowsum(t(NetMatrix_continent), group = colnames(NetMatrix_continent), na.rm = T))
merge_matrix2 <- rowsum(merge_matrix, group = rownames(merge_matrix))


# remove diagonal elements
diag(merge_matrix2) <- 0

# chord plot
chordDiagramFromMatrix(merge_matrix2)

# Create a chord diagram of the network matrix
figs46<- chordDiagram(merge_matrix2, annotationTrack = "grid", preAllocateTracks = 1)
# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

Figure s47

Chord diagram illustration of collaborations across disciplines. Disciplines have been allocated based on the Journal Citation Categories on Web of Science. Collaborations within disciplines are not shown.

fields <- sd %>%
  mutate(
    title = str_to_lower(paper_title),
    ntitle = paste(str_to_lower(str_split_fixed(study_id, "\\_", n = 2)[,1]), paper_title, sep = " "),
    ntitle = str_squish(ntitle),
    Journal_Category_Allocated_Broad = str_replace_all(Journal_Category_Allocated_Broad, "Environmental Science", "Environmental\nScience ")
  ) %>% 
  select(ntitle, Journal_Category_Allocated_Broad)

bib_names <- bib_sco %>% rownames_to_column(., var = "mat_names") %>% 
  mutate(TI2 = tolower(unlist(lapply(data.frame(t(str_split_fixed(TI, " ", n = 15)[,1:14])), 
                                     function(x) str_c(x, collapse  = " ")))),
         name2 = stri_trans_general(tolower(str_split_fixed(SR, " ", n = 2)[,1]), "latin-ascii"),
         TI2 = paste(name2, TI2, sep= " "),
         TI2 = trimws(TI2)) %>% 
  select(TI2, mat_names)

pos <- lapply(bib_names$TI2, function(x) stringdist(fields$ntitle, x))
pos2<- map_dbl(pos, which.min)



# now we can merge two datasets 
bib_names$Journal_Category_Allocated_Broad <- fields$Journal_Category_Allocated_Broad[pos2]

# Creating matrix for bibliometric coupling
NetMatrix <- biblioNetwork(bib_sco, analysis = "coupling", network = "references", sep = ";")

# forcing into a nromal matrix
net_matrix <- as.matrix(NetMatrix)

diag(net_matrix) <- 0 #get rid of counts for the same papers

# replacing names with Journal_Category_Allocated_Broad
rownames(net_matrix) <- bib_names$Journal_Category_Allocated_Broad
colnames(net_matrix) <- bib_names$Journal_Category_Allocated_Broad

# reducing matrix according to discipline_code
rect_matrix<- t(rowsum(t(net_matrix), group = colnames(net_matrix), na.rm = T))
small_matrix <- rowsum(rect_matrix, group = rownames(rect_matrix))

# getting rid of lower triangle (as this is duplication of info)
small_matrix[lower.tri(small_matrix)] <- 0 
par(mar = c(0, 0, 0, 0), mfrow = c(1, 1))


# Create a chord diagram of the network matrix
figs47  <- chordDiagram(small_matrix, annotationTrack = "grid", preAllocateTracks = 1)
# Add a track to label each sector with its name
circos.trackPlotRegion(track.index = 1, panel.fun = function(x, y) {
  xlim = get.cell.meta.data("xlim")
  ylim = get.cell.meta.data("ylim")
  sector.name = get.cell.meta.data("sector.index")
  circos.text(mean(xlim), ylim[1] + 0.2, sector.name, facing = "clockwise", niceFacing = TRUE, adj = c(0, 0.5))
  circos.axis(h = "top", labels.cex = 0.5, major.tick.length = 0.2, sector.index = sector.name, track.index = 2)
}, bg.border = NA)

LS0tDQp0aXRsZTogIlNpeHR5ICB5ZWFycyBzaW5jZSBTaWxlbnQgU3ByaW5nOiBBIHN5c3RlbWF0aWMgcmV2aWV3IG1hcCBhbmQgYmlibGlvbWV0cmljIGFuYWx5c2lzIHByb3ZpZGVzIGEgaG9saXN0aWMgdmlldyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGUgaW1wYWN0cyINCmF1dGhvcjogIkt5bGUgTW9ycmlzb24sIENvcmFsaWUgV2lsbGlhbXMsIExvcmVuem8gUmljb2xmaSwgWWVmZW5nIFlhbmcsICBNYWxnb3JhemF0YSBMYWdpc3osIFNoaW5pY2hpIE5ha2FnYXdhIiANCmRhdGU6ICIyMDIzLTAzLTA5Ig0Kb3V0cHV0OiANCiAgcm1kZm9ybWF0czo6ZG93bmN1dGU6DQogICAgY29kZV9mb2xkaW5nOiBzaG93DQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNA0KZWRpdG9yX29wdGlvbnM6IA0KICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQ0KLS0tDQpgYGB7ciwgaW5jbHVkZSA9IEZBTFNFfQ0Kcm0obGlzdCA9IGxzKCkpDQojIGtuaXRyIHNldHRpbmcNCmtuaXRyOjpvcHRzX2NodW5rJHNldCgNCiAgbWVzc2FnZSA9IEZBTFNFLA0KICB3YXJuaW5nID0gRkFMU0UsIA0KICBjYWNoZSA9IFRSVUUsDQogIGVjaG89VFJVRQ0KKQ0KYGBgDQoNCg0KSW4gdGhpcyBSbWFya2Rvd24gZG9jdW1lbnQgd2UgcHJvdmlkZSB0aGUgZm9sbG93aW5nIHdvcmtmbG93OiAgIA0KDQotIE9iamVjdGl2ZSAwIC0gVG8gZXhhbWluZSB0aGUgdm9sdW1lIGFuZCB0ZW1wb3JhbCB0cmVuZHMgb2YgZXhpc3RpbmcgbWV0YS1hbmFseXNlcyBvbiB0aGUgZWZmZWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzDQoNCi0gT2JqZWN0aXZlIDE6IFRvIGV2YWx1YXRlIHRoZSBtZXRob2RvbG9naWNhbCBwYXR0ZXJucyBhbmQgcXVhbGl0eSBvZiBleGlzdGluZyBtZXRhLWFuYWx5c2VzIHN0dWR5aW5nIHRoZSBlZmZlY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuDQoNCi0gT2JqZWN0aXZlIDIgLiBUbyBleHBsb3JlIHRoZSB2YXJpb3VzIGNoYXJhY3RlcmlzdGljcyBvZiB0aGUgb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcyBsaXRlcmF0dXJlIHN1Y2ggYXMgdGhlIHBlc3RpY2lkZXMgdXNlZCwgdGhlIGltcGFjdHMgZWxpY2l0ZWQgaW4gcmVzcG9uc2UgYW5kIHRoZSBzdWJqZWN0cyB0aGF0IHdlcmUgaW52ZXN0aWdhdGVkLiANCg0KLSBPYmplY3RpdmUgNCAtIFRvIGludmVzdGlnYXRlIHRoZSByZXNlYXJjaCBvdXRwdXRzIGFjcm9zcyBkaWZmZXJlbnQgY291bnRyaWVzLCBjb250aW5lbnRzIGFuZCBkaXNjaXBsaW5lcywgYW5kIGludmVzdGlnYXRlIHRoZSBkZWdyZWUgb2YgY3Jvc3MtY291bnRyeSBjb2xsYWJvcmF0aW9uLg0KIA0KDQojIExvYWQgcGFja2FnZXMgYW5kIGRhdGENCiMjIExvYWQgcGFja2FnZXMgDQpgYGB7ciwgcmVzdWx0cz0iaGlkZSJ9DQpybShsaXN0ID0gbHMoKSkNCnBhY21hbjo6cF9sb2FkKHRpZHl2ZXJzZSwNCmhyYnJ0aGVtZXMsIA0KcGF0Y2h3b3JrLA0KaGVyZSwNCnN0cmluZ3IsDQprbml0ciwNCmZvcm1hdFIsDQpmb3JjYXRzLA0KZ2dwbG90MiwNCmJpYmxpb21ldHJpeCwNCmlncmFwaCwNCnN0cmluZ2ksDQpzdHJpbmdkaXN0LA0KY2lyY2xpemUsDQpnZ2FsbHV2aWFsLA0KZ2dyYXBoKQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSkNCg0KYGBgDQoNCg0KIyMgTG9hZCBkYXRhDQpNYW51YWxseSBleHRyYWN0ZWQgcGlsb3QgZGF0YSBpcyBzdG9yZWQgaW4gZml2ZSBzZXBhcmF0ZSAqKi5jc3YqKiBmaWxlcyByZXByZXNlbnRpbmcgZGlmZmVyZW50IGFzcGVjdHMgb2YgdGhlIGRhdGEgKGV4dHJhY3RlZCB2aWEgc3RydWN0dXJlZCBwcmVkZWZpbmVkIEdvb2dsZSBGb3JtcyAtIG9uZSBwZXIgdGFibGUpLiANCkJpYmxpb2dyYXBoaWMgZGF0YSByZWNvcmRzIGFyZSBleHBvcnRlZCBmcm9tIFNjb3B1cyAoaW5jbHVkaW5nIGNpdGVkIHJlZmVyZW5jZXMgZmllbGQpIGluIC5iaWIgZm9ybWF0IGFuZCBsb2NhbGx5IHNhdmVkIGFzICoqYmliX3Njby5iaWIqKi4gDQpgYGB7ciwgIHJlc3VsdHM9ImhpZGUifQ0KIyBMb2FkIENTViBkYXRhc2V0cw0Kc2QgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJvY3Bfc3JtX3N0dWR5X2RldGFpbHMuY3N2IikpDQpvY3AgPC0gcmVhZF9jc3YoaGVyZSgiZGF0YSIsICJvY3Bfc3JtX29jcF9kZXRhaWxzLmNzdiIpKQ0Kc3ViIDwtIHJlYWRfY3N2KGhlcmUoImRhdGEiLCAib2NwX3NybV9zdWJqZWN0X2RldGFpbHMuY3N2IikpDQppbSA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwgIm9jcF9zcm1faW1wYWN0X2RldGFpbHMuY3N2IikpDQpzcCA8LSByZWFkX2NzdihoZXJlKCJkYXRhIiwgIm9jcF9zcm1fc3BlY2llc19kZXRhaWxzLmNzdiIpKQ0KDQojIExvYWQgQmliVGVYIGRhdGFzZXQNCmJpYl9zY28gPC0gY29udmVydDJkZihoZXJlKCJkYXRhIiwgImJpYl9zY28uYmliIiksIGRic291cmNlID0gInNjb3B1cyIsIGZvcm1hdCA9ICJiaWJ0ZXgiKQ0KYGBgDQoNCiMgT2JqZWN0aXZlIDAgLSBUbyBleGFtaW5lIHRoZSB2b2x1bWUgYW5kIHRlbXBvcmFsIHRyZW5kcyBvZiBleGlzdGluZyBtZXRhLWFuYWx5c2VzIG9uIHRoZSBlZmZlY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMNCg0KIyMgRmlndXJlIDEgDQpBKSBCYXIgY2hhcnQgc2hvd2luZyB0aGUgYW5udWFsIG51bWJlciBvZiBwdWJsaXNoZWQgbWV0YS1hbmFseXNpcyBzeW50aGVzaXNpbmcgcmVzZWFyY2ggb24gdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gRGl2aWRlZCBmb3IgZGlmZmVyZW50IHN1YmplY3RzIG9mIGV4cG9zdXJlLiANCkIpIEFyZWEgZ3JhcGggc2hvd2luZyB0aGUgY3VtdWxhdGl2ZSB0aW1lIHRyZW5kcyBvZiBtZXRhLWFuYWx5c2lzIHN5bnRoZXNpc2luZyByZXNlYXJjaCBvbiB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBEaXZpZGVkIGZvciBkaWZmZXJlbnQgc3ViamVjdHMgb2YgZXhwb3N1cmUuDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEyfQ0KDQojIEpvaW4gdGhlIHN0dWR5IGFuZCBzdWJqZWN0IGRhdGFzZXRzDQpzZF9zdWIgPC0gbGVmdF9qb2luKHNkLCBzdWIsIGJ5ID0gInN0dWR5X2lkIikNCg0KIyBDb3VudCB0aGUgbnVtYmVyIG9mIHB1YmxpY2F0aW9ucyBwZXIgeWVhciBhbmQgY2FsY3VsYXRlIGN1bXVsYXRpdmUgc3VtDQpzZDEgPC0gc2QgJT4lDQogIGNvdW50KHB1YmxpY2F0aW9uX3llYXIpICU+JQ0KICBtdXRhdGUobl9jdW11bGF0aXZlID0gY3Vtc3VtKG4pKQ0KDQoNCiMgQ3JlYXRlIGEgdGhlbWUgZm9yIHRoZSBjb3VudCBwbG90cyANCnRoZW1lX2NvdW50IDwtIGZ1bmN0aW9uKCkgew0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIGxpbmV0eXBlID0gImRhc2hlZCIpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfbGluZShzaXplID0gMS4yKSwNCiAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwLCBmYWNlID0gImJvbGQiKSwNCiAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEsIHNpemUgPSAxNSwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgY29sb3IgPSAiIzY2NjY2NiIpLA0KICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICApDQp9DQoNCg0KIyBDcmVhdGUgdGhlIGFubnVhbCBjb3VudCBwbG90DQpmaWcxYSA8LSBzZF9zdWIgJT4lDQogIG11dGF0ZShzdWJqZWN0cyA9IHN0cnNwbGl0KHN1YmplY3QsICIsXFxzKyIpKSAlPiUNCiAgdW5uZXN0KHN1YmplY3RzKSAlPiUNCiAgY291bnQocHVibGljYXRpb25feWVhciwgc3ViamVjdHMpICU+JQ0KICBncm91cF9ieShzdWJqZWN0cyA9IHJlb3JkZXIoc3ViamVjdHMsIG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHVibGljYXRpb25feWVhciwgeSA9IG4sIGZpbGwgPSBzdWJqZWN0cykpICsNCiAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAic3RhY2siLCBhbHBoYSA9IDAuNykgKw0KICAgIGdlb21fdGV4dChhZXMobGFiZWwgPSBuKSwgcG9zaXRpb24gPSBwb3NpdGlvbl9zdGFjayh2anVzdCA9IDAuNiksIA0KICAgICAgICAgICAgICBmb250ZmFjZSA9ICJib2xkIiwgY29sb3IgPSAid2hpdGUiLCBzaXplID0gNiwgaGp1c3QgPSAwLjQpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihzZDEkcHVibGljYXRpb25feWVhciksIG1heChzZDEkcHVibGljYXRpb25feWVhciksIGJ5ID0gMSksIA0KICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBleHBhbnNpb24oMCwwKSkgKyAgDQogICAgc2NhbGVfeV9jb250aW51b3VzKCJBbm51YWwgQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwxNSkpICsNCiAgICBsYWJzKHkgPSAiQXJ0aWNsZSBDb3VudCIsIHRhZyA9ICJBIiwgZmlsbCA9ICJTdWJqZWN0cyIpICsNCiAgICB0aGVtZV9jb3VudCgpICsNCiAgICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKw0KICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKQ0KDQoNCiMgQ3JlYXRlIHRoZSBjdW11bGF0aXZlIGNvdW50IHBsb3QNCmZpZzFiIDwtIHNkX3N1YiAlPiUNCiAgbXV0YXRlKHN1YmplY3RzID0gc3Ryc3BsaXQoc3ViamVjdCwgIixcXHMrIikpICU+JQ0KICB1bm5lc3Qoc3ViamVjdHMpICU+JQ0KICBjb3VudChwdWJsaWNhdGlvbl95ZWFyLCBzdWJqZWN0cykgJT4lDQogIGdyb3VwX2J5KHN1YmplY3RzID0gcmVvcmRlcihzdWJqZWN0cywgbikpICU+JQ0KICBtdXRhdGUobl9jdW11bGF0aXZlID0gY3Vtc3VtKG4pKSAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gcHVibGljYXRpb25feWVhciwgeSA9IG5fY3VtdWxhdGl2ZSwgZmlsbCA9IHN1YmplY3RzKSkgKw0KICAgIGdlb21fYXJlYShzaXplID0gMS4yLCBhbHBoYSA9IDAuNykgKw0KICAgIHNjYWxlX3lfY29udGludW91cygiQ3VtdWxhdGl2ZSBBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLDExNSkpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihzZF9zdWIkcHVibGljYXRpb25feWVhciksIG1heChzZF9zdWIkcHVibGljYXRpb25feWVhciksIGJ5ID0gMSksIA0KICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBleHBhbnNpb24oMCwwKSkgKyAgDQogICAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkN1bXVsYXRpdmUgQXJ0aWNsZSBDb3VudCIsIHRhZyA9ICJCIiwgZmlsbCA9ICJTdWJqZWN0cyIpICsNCiAgICB0aGVtZV9jb3VudCgpICsNCiAgICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIikgKw0KICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKQ0KDQojIENvbWJpbmUgdGhlIHR3byBwbG90cw0KZmlnMSA8LSBmaWcxYSAvIGZpZzFiDQpmaWcxDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnMS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzEuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzNCANCkEpIEJhciBjaGFydCBzaG93aW5nIHRoZSBhbm51YWwgbnVtYmVyIG9mIHB1Ymxpc2hlZCBtZXRhLWFuYWx5c2VzIHN5bnRoZXNpc2luZyByZXNlYXJjaCBvbiB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiAgDQpCKSBMaW5lIGdyYXBoIHNob3dpbmcgdGhlIGN1bXVsYXRpdmUgdGltZSB0cmVuZHMgb2YgbWV0YS1hbmFseXNlcyBzeW50aGVzaXNpbmcgcmVzZWFyY2ggb24gdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTJ9DQojIENyZWF0ZSB0aGUgYW5udWFsIENvdW50IFBsb3QNCmZpZ3M0YSA8LSBzZDEgJT4lDQogIGdncGxvdChhZXMoeCA9IHB1YmxpY2F0aW9uX3llYXIsIHkgPSBuKSkgKw0KICAgIGdlb21fY29sKGZpbGwgPSAiIzFiOWU3NyIsIGFscGhhID0gMC43KSArDQogICAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC42KSwgDQogICAgICAgICAgICAgIGZvbnRmYWNlID0gImJvbGQiLCBjb2xvciA9ICJ3aGl0ZSIsIHNpemUgPSA2LCBoanVzdCA9IDAuNCkgKw0KICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEobWluKHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgbWF4KHNkMSRwdWJsaWNhdGlvbl95ZWFyKSwgYnkgPSAxKSwgDQogICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZCA9IGV4cGFuc2lvbigwLDEpKSArDQogICAgc2NhbGVfeV9jb250aW51b3VzKCJBbm51YWwgQXJ0aWNsZSBDb3VudCIsIGxpbWl0cyA9IGMoMCwxNSkpICsNCiAgICBsYWJzKHggPSAiWWVhciIsIHRhZyA9ICJBIikgKw0KICAgIHRoZW1lX2NvdW50KCkgKw0KICAgIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkNCg0KDQojIENyZWF0ZSB0aGUgY3VtdWxhdGl2ZSBDb3VudCBQbG90DQpmaWdzNGIgPC0gc2QxICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwdWJsaWNhdGlvbl95ZWFyLCB5ID0gbl9jdW11bGF0aXZlKSkgKw0KICAgIGdlb21fbGluZShjb2xvciA9ICIjNzU3MGIzIiwgc2l6ZSA9IDEsIGxpbmV0eXBlID0gInNvbGlkIikgKw0KICAgIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgc2l6ZSA9IDYsIGZpbGwgPSAiIzc1NzBiMyIsIHN0cm9rZSA9IDApICsNCiAgICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbl9jdW11bGF0aXZlKSwgaGp1c3QgPSAwLjIsIHZqdXN0ID0gLTEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKG1pbihzZDEkcHVibGljYXRpb25feWVhciksIG1heChzZDEkcHVibGljYXRpb25feWVhciksIGJ5ID0gMSksIA0KICAgICAgICAgICAgICAgICAgICAgICBleHBhbmQgPSBleHBhbnNpb24oMCwxKSkgKw0KICAgIHNjYWxlX3lfY29udGludW91cygiQ3VtdWxhdGl2ZSBBcnRpY2xlIENvdW50IiwgbGltaXRzID0gYygwLDEyMCkpICsNCiAgICBsYWJzKHggPSAiWWVhciIsIHRhZyA9ICJCIikgKw0KICAgIHRoZW1lX2NvdW50KCkNCg0KIyBDb21iaW5lIHRoZSB0d28gcGxvdHMNCmZpZ3M0IDwtIGZpZ3M0YSAvIGZpZ3M0Yg0KZmlnczQNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M0LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMgT2JqZWN0aXZlIDENClRvIGV2YWx1YXRlIHRoZSBtZXRob2RvbG9naWNhbCBwYXR0ZXJucyBhbmQgcXVhbGl0eSBvZiBleGlzdGluZyBtZXRhLWFuYWx5c2VzIHN0dWR5aW5nIHRoZSBlZmZlY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIA0KDQojIyBGaWd1cmUgczUgDQpCYXIgcGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCB0b3RhbCBjb3VudCBvZiBzY2llbnRpZmljIGxpdGVyYXR1cmUgZGF0YWJhc2VzIHVzZWQgaW4gbWV0YS1hbmFseXNlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIE5vdGUgdGhhdCBzb21lIG1ldGEtYW5hbHlzZXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVkIG11bHRpcGxlIHNjaWVudGlmaWMgbGl0ZXJhdHVyZSBkYXRhYmFzZXMuIFRoZSAiT3RoZXIgZGF0YWJhc2VzIiBjYXRlZ29yeSBpbmNsdWRlcyBhbGwgZGF0YWJhc2VzIHdpdGggYSBjb3VudCBvZiAzIG9yIGxlc3MuDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpkYXRhYmFzZV9jb3VudCA8LSBzZCAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoZGF0YWJhc2Vfc2VhcmNoLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGRhdGFiYXNlX3NlYXJjaCkgJT4lIA0KICBmaWx0ZXIoZGF0YWJhc2Vfc2VhcmNoICE9ICJub3QgcmVwb3J0ZWQiKSAlPiUgDQogIGFycmFuZ2UoZGVzYyhuKSkgJT4lIA0KICBtdXRhdGUoZGF0YWJhc2Vfc2VhcmNoID0gaWZlbHNlKG48PSAzLCAiT3RoZXIgZGF0YWJhc2VzIiwgYXMuY2hhcmFjdGVyKGRhdGFiYXNlX3NlYXJjaCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoZGF0YWJhc2Vfc2VhcmNoKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZGF0YWJhc2VfcGN0IDwtIGRhdGFiYXNlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oZGF0YWJhc2VfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgYSBzdGFuZGFyZCB0aGVtZSBmb3IgdGhlIHN1cHBsZW1lbnQgcGxvdHMNCnRoZW1lX3N1cHBsIDwtIGZ1bmN0aW9uKCkgew0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgKQ0KfQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KZmlnczUgPC0gZGF0YWJhc2VfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGRhdGFiYXNlX3NlYXJjaCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGRhdGFiYXNlX3NlYXJjaCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IGRhdGFiYXNlX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChkYXRhYmFzZV9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfc3VwcGwoKQ0KDQpmaWdzNQ0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M1LnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczUuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHM2DQpBbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgdGhlIHNjaWVudGlmaWMgbGl0ZXJhdHVyZSBkYXRhYmFzZSB1c2VkLiBGaWx0ZXJlZCBmb3Igc2NpZW50aWZpYyBsaXRlcmF0dXJlIGRhdGFiYXNlIGNvdW50cyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMy4gDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBSZW5hbWUgRW52aXJvbm1lbnRhbCBTY2llbmNlDQpzZCA8LSBzZCAlPiUNCiAgbXV0YXRlKEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkID0gc3RyX3JlcGxhY2UoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsICJFbnZpcm9ubWVudGFsIFNjaWVuY2UiLCAiRW52aXJvbm1lbnRhbFxuU2NpZW5jZSIpKQ0KDQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpkYXRhYmFzZV9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhkYXRhYmFzZV9zZWFyY2gsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBjb3VudChkYXRhYmFzZV9zZWFyY2gsIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkKSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShkYXRhYmFzZV9zZWFyY2gpICU+JSANCiAgICBmaWx0ZXIoc3VtKGZyZXEpID49IDMpICU+JSANCiAgICBmaWx0ZXIoZGF0YWJhc2Vfc2VhcmNoICE9ICJOQSIpDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpmaWdzNiA8LSBkYXRhYmFzZV9hbGx1dmlhbCAlPiUgDQpnZ3Bsb3QoYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBheGlzMiA9IGRhdGFiYXNlX3NlYXJjaCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJEYXRhYmFzZSBTZWFyY2giKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICB5bGFiKCJGcmVxdWVuY3kiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS80LjUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gNikgKw0KICBsYWJzKHg9ICJWYXJpYWJsZXMiLCB5ID0gIkZyZXF1ZW5jeSIsIGZpbGwgPSAiSm91cm5hbCBDYXRlZ29yeSBBbGxvY2F0ZWQiKSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczYNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNi5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M2LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KICANCmBgYA0KDQojIyBGaWd1cmUgczcgDQpCYXIgcGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCB0b3RhbCBjb3VudCBvZiBlZmZlY3Qgc2l6ZSBjYWxjdWxhdGlvbiB0eXBlcyB1c2VkIGluIG1ldGEtYW5hbHlzZXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlIHRoYXQgc29tZSBtZXRhLWFuYWx5c2VzIG1heSBjb250cmlidXRlIHRvIG11bHRpcGxlIHNlY3Rpb25zIGlmIHRoZSBzdHVkeSBpbnZvbHZlZCBtdWx0aXBsZSBlZmZlY3Qgc2l6ZSBjYWxjdWxhdGlvbnMuIFRoZSAiT3RoZXIgZWZmZWN0IHNpemVzIiBjYXRlZ29yeSBpbmNsdWRlcyBhbGwgZWZmZWN0IHNpemVzIHdpdGggYSBjb3VudCBvZiAyIG9yIGxlc3MuDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQplZmZlY3RzaXplX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhlZmZlY3Rfc2l6ZSwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChlZmZlY3Rfc2l6ZSkgJT4lDQogIGZpbHRlcihlZmZlY3Rfc2l6ZSAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKGVmZmVjdF9zaXplID0gaWZlbHNlKG48PSAyLCAib3RoZXIgZWZmZWN0IHNpemVzIiwgYXMuY2hhcmFjdGVyKGVmZmVjdF9zaXplKSkpICU+JSANCiAgZ3JvdXBfYnkoZWZmZWN0X3NpemUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KZWZmZWN0c2l6ZV9wY3QgPC0gZWZmZWN0c2l6ZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGVmZmVjdHNpemVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmZpZ3M3IDwtICBlZmZlY3RzaXplX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihlZmZlY3Rfc2l6ZSwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGVmZmVjdF9zaXplLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gZWZmZWN0c2l6ZV9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgoZWZmZWN0c2l6ZV9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfc3VwcGwoKQ0KDQpmaWdzNw0KDQojICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNy5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojICBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzNy5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHM4DQpBbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgdGhlIGVmZmVjdCBzaXplIHVzZWQuIEZpbHRlcmVkIGZvciBzY2llbnRpZmljIGxpdGVyYXR1cmUgZGF0YWJhc2UgY291bnRzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAzLg0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmVmZmVjdHNpemVfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoZWZmZWN0X3NpemUsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIHNlcCA9ICIvXFxzKyIpICU+JSANCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShlZmZlY3Rfc2l6ZSkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBlZmZlY3Rfc2l6ZSkgJT4lIA0KICAgIGNvdW50KGVmZmVjdF9zaXplLCBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoZWZmZWN0X3NpemUpIA0KDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpmaWdzOCA8LSBlZmZlY3RzaXplX2FsbHV2aWFsICU+JSANCmdncGxvdChhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGF4aXMyID0gZWZmZWN0X3NpemUpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDYXRlZ29yeSIsICJFZmZlY3QgU2l6ZSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS8yLjUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gNSkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICBsYWJzKHg9ICJWYXJpYWJsZXMiLCB5ID0gIkZyZXF1ZW5jeSIsIGZpbGwgPSAiSm91cm5hbCBDYXRlZ29yeSBBbGxvY2F0ZWQiKSArDQogIHRoZW1lX3N1cHBsKCkNCiAgDQpmaWdzOA0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M4LnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczguanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzOQ0KQmFyIHBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgdG90YWwgY291bnQgb2Ygc29mdHdhcmUgZm9yIGFuYWx5c2lzIHVzZWQgaW4gbWV0YS1hbmFseXNlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIE5vdGUgdGhhdCBzb21lIG1ldGEtYW5hbHlzZXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVkIG11bHRpcGxlIHNvZnR3YXJlLiANCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnNvZnR3YXJlX2NvdW50IDwtIHNkICU+JQ0KICBzZXBhcmF0ZV9yb3dzKHNvZnR3YXJlX2FuYWx5c2lzLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgbXV0YXRlKHNvZnR3YXJlX2FuYWx5c2lzID0gaWZlbHNlKGdyZXBsKCJjb21wcmVoZW5zaXZlIG1ldGEtYW5hbHlzaXMiLCBzb2Z0d2FyZV9hbmFseXNpcyksICJDTUFTIiwgc29mdHdhcmVfYW5hbHlzaXMpKSAlPiUNCiAgbXV0YXRlKHNvZnR3YXJlX2FuYWx5c2lzID0gaWZlbHNlKGdyZXBsKCJub3QgcmVwb3J0ZWQiLCBzb2Z0d2FyZV9hbmFseXNpcyksICJubyBzb2Z0d2FyZSByZXBvcnRlZCIsIHNvZnR3YXJlX2FuYWx5c2lzKSkgICU+JSANCiAgY291bnQoc29mdHdhcmVfYW5hbHlzaXMpICU+JQ0KICBmaWx0ZXIoc29mdHdhcmVfYW5hbHlzaXMgIT0gIk5BIikgJT4lDQogIGdyb3VwX2J5KHNvZnR3YXJlX2FuYWx5c2lzKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0Kc29mdHdhcmVfcGN0IDwtIHNvZnR3YXJlX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oc29mdHdhcmVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmZpZ3M5IDwtIHNvZnR3YXJlX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihzb2Z0d2FyZV9hbmFseXNpcywgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKHNvZnR3YXJlX2FuYWx5c2lzLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gc29mdHdhcmVfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KHNvZnR3YXJlX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3M5DQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczkucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzOS5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczEwIA0KQWxsdXZpYWwgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkgYW5kIHRoZSBzb2Z0d2FyZSB1c2VkIGZvciBhbmFseXNpcy4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpzb2Z0d2FyZV9hbmFseXNpc19hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhzb2Z0d2FyZV9hbmFseXNpcywgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2VwID0gIi9cXHMrIikgJT4lIA0KICBtdXRhdGUoc29mdHdhcmVfYW5hbHlzaXMgPSBpZmVsc2UoZ3JlcGwoImNvbXByZWhlbnNpdmUgbWV0YS1hbmFseXNpcyIsIHNvZnR3YXJlX2FuYWx5c2lzKSwgIkNNQVMiLCBzb2Z0d2FyZV9hbmFseXNpcykpICU+JQ0KICBtdXRhdGUoc29mdHdhcmVfYW5hbHlzaXMgPSBpZmVsc2UoZ3JlcGwoIm5vdCByZXBvcnRlZCIsIHNvZnR3YXJlX2FuYWx5c2lzKSwgIm5vIHNvZnR3YXJlIHJlcG9ydGVkIiwgc29mdHdhcmVfYW5hbHlzaXMpKSAgJT4lIA0KICAgIGZpbHRlcighaXMubmEoc29mdHdhcmVfYW5hbHlzaXMpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc29mdHdhcmVfYW5hbHlzaXMpICU+JSANCiAgICBjb3VudChzb2Z0d2FyZV9hbmFseXNpcywgSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KHNvZnR3YXJlX2FuYWx5c2lzKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdCBmb3IgU29mdHdhcmUgQW5hbHlzaXMNCmZpZ3MxMCA8LSBzb2Z0d2FyZV9hbmFseXNpc19hbGx1dmlhbCAlPiUgDQpnZ3Bsb3QoYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBheGlzMiA9IHNvZnR3YXJlX2FuYWx5c2lzKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2F0ZWdvcnkiLCAiU29mdHdhcmUgQW5hbHlzaXMiKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpKSArDQogIGdlb21fc3RyYXR1bSh3aWR0aCA9IDEvNCwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIHNpemUgPSA2KSArDQogIGxhYnMoeD0gIlZhcmlhYmxlcyIsIHkgPSAiRnJlcXVlbmN5IiwgZmlsbCA9ICJKb3VybmFsIENhdGVnb3J5IEFsbG9jYXRlZCIpICsNCiAgdGhlbWVfc3VwcGwoKQ0KDQpmaWdzMTANCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTAucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTAuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxMQ0KQmFyIHBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgdG90YWwgY291bnQgb2YgaGV0ZXJvZ2VuZWl0eSBhc3Nlc3NtZW50IG1ldGhvZHMgdXNlZCBpbiBtZXRhLWFuYWx5c2VzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gTm90ZSB0aGF0IHNvbWUgbWV0YS1hbmFseXNlcyBtYXkgY29udHJpYnV0ZSB0byBtdWx0aXBsZSBzZWN0aW9ucyBpZiB0aGUgc3R1ZHkgaW52b2x2ZWQgbXVsdGlwbGUgaGV0ZXJvZ2VuZWl0eSBhc3Nlc3NtZW50cy4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmhldGVyb2dlbmVpdHlfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkgJT4lDQogICAgbXV0YXRlKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QgPSBpZmVsc2UoZ3JlcGwoIm5vdCByZXBvcnRlZCIsIGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpLCAibm8gaGV0ZXJvZ2VuZWl0eVxubWVhc3VyZSByZXBvcnRlZCIsIGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpKSAgJT4lIA0KICBmaWx0ZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgICBncm91cF9ieShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmhldGVyb2dlbmVpdHlfcGN0IDwtIGhldGVyb2dlbmVpdHlfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShoZXRlcm9nZW5laXR5X2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpmaWdzMTEgPC0gaGV0ZXJvZ2VuZWl0eV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBoZXRlcm9nZW5laXR5X3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChoZXRlcm9nZW5laXR5X2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxMQ0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMS5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KIA0KIyMgRmlndXJlIHMxMiANCkFsbHV2aWFsIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIEpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IGFuZCBoZXRlcm9nZW5laXR5IGFzc2Vzc21lbnQgbWV0aG9kLg0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmhldGVyb2dlbmVpdHlfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2VwID0gIi9cXHMrIikgJT4lIA0KICBtdXRhdGUoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCA9IGlmZWxzZShncmVwbCgibm90IHJlcG9ydGVkIiwgaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCksICJubyBoZXRlcm9nZW5laXR5XG5tZWFzdXJlIHJlcG9ydGVkIiwgaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkpICAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSkgJT4lDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpICU+JSANCiAgICBjb3VudChoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kLCBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCkgDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpmaWdzMTIgPC0gaGV0ZXJvZ2VuZWl0eV9hbGx1dmlhbCAlPiUgDQpnZ3Bsb3QoYWVzKHkgPSBmcmVxICxheGlzMSA9IEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBheGlzMiA9IGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiSGV0ZXJvZ2VuZWl0eSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS80LjUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gNikgKw0KICBsYWJzKHg9ICJWYXJpYWJsZXMiLCB5ID0gIkZyZXF1ZW5jeSIsIGZpbGwgPSAiSm91cm5hbCBDYXRlZ29yeSBBbGxvY2F0ZWQiKSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczEyDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczEyLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczEyLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KIA0KIyMgRmlndXJlIHMxMw0KQmFyIHBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgdG90YWwgY291bnQgb2Ygc2Vuc2l0aXZpdHkgYW5hbHlzZXMgY29uZHVjdGVkIGluIG1ldGEtYW5hbHlzZXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlIHRoYXQgc29tZSBtZXRhLWFuYWx5c2VzIG1heSBjb250cmlidXRlIHRvIG11bHRpcGxlIHNlY3Rpb25zIGlmIHRoZSBzdHVkeSBpbnZvbHZlZCBtdWx0aXBsZSBzZW5zaXRpdml0eSBhbmFseXNlcy4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnNlbnNpdGl2aXR5X2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgY291bnQoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUNCiAgZmlsdGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCAhPSAiTkEiKSAlPiUgICANCiAgZ3JvdXBfYnkoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnNlbnNpdGl2aXR5X3BjdCA8LSBzZW5zaXRpdml0eV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHNlbnNpdGl2aXR5X2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpmaWdzMTMgPC0gc2Vuc2l0aXZpdHlfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHNlbnNpdGl2aXR5X3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChzZW5zaXRpdml0eV9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxMw0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMy5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxMy5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczE0DQpBbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgc2Vuc2l0aXZpdHkgYW5hbHlzaXMuDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0Kc2Vuc2l0aXZpdHlfYW5hbHlzaXNfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3Moc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBzZXAgPSAiL1xccysiKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSAlPiUgDQogICAgY291bnQoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kLCBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkoc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZmlnczE0IDwtIHNlbnNpdGl2aXR5X2FuYWx5c2lzX2FsbHV2aWFsICU+JSANCmdncGxvdChhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGF4aXMyID0gc2Vuc2l0aXZpdHlfYW5hbHlzaXNfbWV0aG9kKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlNlbnNpdGl2aXR5IEFuYWx5c2lzIE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS80LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDUpICsNCiAgbGFicyh4PSAiVmFyaWFibGVzIiwgeSA9ICJGcmVxdWVuY3kiLCBmaWxsID0gIkpvdXJuYWwgQ2F0ZWdvcnkgQWxsb2NhdGVkIikgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxNA0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNC5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczE1IA0KQmFyIHBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgdG90YWwgY291bnQgb2YgYmlhcyB0eXBlcyBhc3Nlc3NlZCBpbiBtZXRhLWFuYWx5c2VzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gTm90ZSB0aGF0IHNvbWUgbWV0YS1hbmFseXNlcyBtYXkgY29udHJpYnV0ZSB0byBtdWx0aXBsZSBzZWN0aW9ucyBpZiB0aGUgc3R1ZHkgaW52b2x2ZWQgdGhlIGFzc2Vzc21lbnQgb2YgbXVsdGlwbGUgYmlhcyB0eXBlcy4gDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpiaWFzX3R5cGVfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGJpYXNfYXNzZXNzbWVudF90eXBlLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGJpYXNfYXNzZXNzbWVudF90eXBlKSAlPiUNCiAgIGZpbHRlcihiaWFzX2Fzc2Vzc21lbnRfdHlwZSAhPSAiTkEiKSAlPiUNCiAgZ3JvdXBfYnkoYmlhc19hc3Nlc3NtZW50X3R5cGUpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0KYmlhc190eXBlX3BjdCA8LSBiaWFzX3R5cGVfY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bShiaWFzX3R5cGVfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmZpZ3MxNSA8LSBiaWFzX3R5cGVfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGJpYXNfYXNzZXNzbWVudF90eXBlLCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIoYmlhc19hc3Nlc3NtZW50X3R5cGUsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBiaWFzX3R5cGVfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KGJpYXNfdHlwZV9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfc3VwcGwoKQ0KDQpmaWdzMTUNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTUucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTUuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQpgYGANCg0KIyMgRmlndXJlIHMxNg0KQWxsdXZpYWwgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkgYW5kIGJpYXMgYXNzZXNzbWVudCBtZXRob2QNCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpiaWFzX2Fzc2Vzc21lbnRfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoYmlhc19hc3Nlc3NtZW50X3R5cGUsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIHNlcGFyYXRlX3Jvd3MoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIHNlcCA9ICIvXFxzKyIpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKGJpYXNfYXNzZXNzbWVudF90eXBlKSkgJT4lDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGJpYXNfYXNzZXNzbWVudF90eXBlKSAlPiUgDQogICAgY291bnQoYmlhc19hc3Nlc3NtZW50X3R5cGUsIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkKSAlPiUgDQogICAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JSANCiAgICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfdHlwZSkNCg0KIyBDcmVhdGUgdGhlIEFsbHV2aWFsIHBsb3QNCmZpZ3MxNiA8LSBiaWFzX2Fzc2Vzc21lbnRfYWxsdXZpYWwgJT4lIA0KZ2dwbG90KGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgYXhpczIgPSBiaWFzX2Fzc2Vzc21lbnRfdHlwZSkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJCaWFzIEFzc2Vzc21lbnQgVHlwZSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS80LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDYpICsNCiAgbGFicyh4PSAiVmFyaWFibGVzIiwgeSA9ICJGcmVxdWVuY3kiLCBmaWxsID0gIkpvdXJuYWwgQ2F0ZWdvcnkgQWxsb2NhdGVkIikgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxNg0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNi5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNi5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHMxNyANCkJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIHRvdGFsIGNvdW50IG9mIGJpYXMgbWV0aG9kb2xvZ2llcyB1c2VkIGluIG1ldGEtYW5hbHlzZXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlIHRoYXQgc29tZSBtZXRhLWFuYWx5c2VzIG1heSBjb250cmlidXRlIHRvIG11bHRpcGxlIHNlY3Rpb25zIGlmIHRoZSBzdHVkeSBpbnZvbHZlZCB0aGUgdXNlIG9mIG11bHRpcGxlIGJpYXMgYXNzZXNzbWVudCBtZXRob2RvbG9naWVzLiANCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX2NvdW50IDwtIHNkICU+JSANCiAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGJpYXNfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBmaWx0ZXIoYmlhc19hc3Nlc3NtZW50X21ldGhvZCAhPSAiTkEiKSAlPiUNCiAgICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfbWV0aG9kX3BjdCA8LSBiaWFzX21ldGhvZF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKGJpYXNfbWV0aG9kX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpmaWdzMTcgPC0gYmlhc19tZXRob2RfY291bnQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGJpYXNfYXNzZXNzbWVudF9tZXRob2QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gYmlhc19tZXRob2RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KGJpYXNfbWV0aG9kX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxNw0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNy5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxNy5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KDQojIyBGaWd1cmUgczE4DQpBbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgYmlhcyBhc3Nlc3NtZW50IG1ldGhvZC4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIERhdGEgVHJhbnNmb3JtYXRpb24gDQpiaWFzX2Fzc2Vzc21lbnRfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighaXMubmEoYmlhc19hc3Nlc3NtZW50X21ldGhvZCkpICU+JQ0KICAgIGdyb3VwX2J5KEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUgDQogICAgY291bnQoYmlhc19hc3Nlc3NtZW50X21ldGhvZCwgSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF9tZXRob2QpDQoNCiMgQ3JlYXRlIHRoZSBBbGx1dmlhbCBwbG90DQpmaWdzMTggPC0gYmlhc19hc3Nlc3NtZW50X2FsbHV2aWFsICU+JSANCiAgZ2dwbG90KGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgYXhpczIgPSBiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIkJpYXMgQXNzZXNzbWVudCBNZXRob2QiKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpKSArDQogIGdlb21fc3RyYXR1bSh3aWR0aCA9IDEvMy41LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDYpICsNCiAgbGFicyh4PSAiVmFyaWFibGVzIiwgeSA9ICJGcmVxdWVuY3kiLCBmaWxsID0gIkpvdXJuYWwgQ2F0ZWdvcnkgQWxsb2NhdGVkIikgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MxOA0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxOC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MxOC5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczE5DQpCYXIgcGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCB0b3RhbCBjb3VudCBvZiBiaWFzIHZpc3VhbGl6YXRpb25zIHVzZWQgaW4gbWV0YS1hbmFseXNlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIE5vdGUgdGhhdCBzb21lIG1ldGEtYW5hbHlzZXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVkIHRoZSB1c2Ugb2YgbXVsdGlwbGUgYmlhcyB2aXN1YWxpemF0aW9ucy4gDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpiaWFzX3Zpc3VhbGl6YXRpb25fY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uKSAlPiUNCiAgZmlsdGVyKGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uICE9ICJOQSIpICU+JQ0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmJpYXNfdmlzdWFsaXphdGlvbl9wY3QgPC0gYmlhc192aXN1YWxpemF0aW9uX2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4gLyBzdW0oYmlhc192aXN1YWxpemF0aW9uX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpmaWdzMTkgPC0gYmlhc192aXN1YWxpemF0aW9uX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihiaWFzX2Fzc2Vzc21lbnRfdmlzdWFsaXphdGlvbiwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gYmlhc192aXN1YWxpemF0aW9uX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMSksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChiaWFzX3Zpc3VhbGl6YXRpb25fY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogdGhlbWVfc3VwcGwoKQ0KDQpmaWdzMTkNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTkucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMTkuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzMjANCkFsbHV2aWFsIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIEpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IGFuZCBiaWFzIHZpc3VhbGl6YXRpb24gbWV0aG9kLg0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCmJpYXNfdml6dWFsaXNhdGlvbl9hbGx1dmlhbCA8LSBzZCAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhiaWFzX2Fzc2Vzc21lbnRfdmlzdWFsaXphdGlvbiwgc2VwID0gIixcXHMrIikgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2VwID0gIi9cXHMrIikgJT4lIA0KICAgIGZpbHRlcighaXMubmEoYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24pKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24pICU+JSANCiAgICBjb3VudChiaWFzX2Fzc2Vzc21lbnRfdmlzdWFsaXphdGlvbiwgSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KGJpYXNfYXNzZXNzbWVudF92aXN1YWxpemF0aW9uKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZmlnczIwIDwtIGJpYXNfdml6dWFsaXNhdGlvbl9hbGx1dmlhbCAlPiUgDQogIGdncGxvdChhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGF4aXMyID0gYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24pKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiQmlhcyBBc3Nlc3NtZW50IE1ldGhvZCIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS80LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDYpICsNCiAgbGFicyh4PSAiVmFyaWFibGVzIiwgeSA9ICJGcmVxdWVuY3kiLCBmaWxsID0gIkpvdXJuYWwgQ2F0ZWdvcnkgQWxsb2NhdGVkIikgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MyMA0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyMC5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyMC5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczIxIA0KQmFyIHBsb3Qgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBhbmQgdG90YWwgY291bnQgb2YgcmlzayBvZiBiaWFzIHRlc3RzIHVzZWQgaW4gbWV0YS1hbmFseXNlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIE5vdGUgdGhhdCBzb21lIG1ldGEtYW5hbHlzZXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVkIHRoZSB1c2Ugb2YgbXVsdGlwbGUgcmlzayBvZiBiaWFzIHRlc3RzLiANCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnJvYl9tZXRob2RfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKHJvYl9hc3Nlc3NtZW50X21ldGhvZCwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChyb2JfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBmaWx0ZXIocm9iX2Fzc2Vzc21lbnRfbWV0aG9kICE9ICJOQSIpICU+JQ0KICBncm91cF9ieShyb2JfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0Kcm9iX21ldGhvZF9wY3QgPC0gcm9iX21ldGhvZF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHJvYl9tZXRob2RfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbiAqIDEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QNCmZpZ3MyMSA8LSByb2JfbWV0aG9kX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihyb2JfYXNzZXNzbWVudF9tZXRob2QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihyb2JfYXNzZXNzbWVudF9tZXRob2QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSByb2JfbWV0aG9kX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChyb2JfbWV0aG9kX2NvdW50JG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9zdXBwbCgpDQoNCmZpZ3MyMQ0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyMS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyMS5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHMyMg0KQWxsdXZpYWwgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkgYW5kIHJpc2sgb2YgYmlhcyBtZXRob2RvbG9neS4gDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBEYXRhIFRyYW5zZm9ybWF0aW9uIA0Kcm9ibWV0aG9kX2FsbHV2aWFsIDwtIHNkICU+JSANCiAgICAgc2VwYXJhdGVfcm93cyhyb2JfYXNzZXNzbWVudF9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIGZpbHRlcighaXMubmEocm9iX2Fzc2Vzc21lbnRfbWV0aG9kKSkgJT4lDQogICAgc2VwYXJhdGVfcm93cyhKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgc2VwID0gIi9cXHMrIikgJT4lDQogICAgZ3JvdXBfYnkoSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIHJvYl9hc3Nlc3NtZW50X21ldGhvZCkgJT4lIA0KICAgIGNvdW50KHJvYl9hc3Nlc3NtZW50X21ldGhvZCwgSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KHJvYl9hc3Nlc3NtZW50X21ldGhvZCkgDQoNCg0KIyBDcmVhdGUgdGhlIEFsbHV2aWFsIHBsb3QNCmZpZ3MyMiA8LSByb2JtZXRob2RfYWxsdXZpYWwgJT4lIA0KZ2dwbG90KGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgYXhpczIgPSByb2JfYXNzZXNzbWVudF9tZXRob2QpKSArDQogIHNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gYygiSm91cm5hbCBDaXRhdGlvbiBSZXBvcnQgQ2F0ZWdvcnkiLCAiUk9CIEFzc2Vzc21lbnQgTWV0aG9kIiksIGV4cGFuZCA9IGMoLjA1LCAuMDUpKSArDQogIHhsYWIoIlZhcmlhYmxlcyIpICsNCiAgZ2VvbV9hbGx1dml1bShhZXMoZmlsbCA9IEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkKSkgKw0KICBnZW9tX3N0cmF0dW0od2lkdGggPSAxLzMsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KHN0YXQgPSAic3RyYXR1bSIsIGFlcyhsYWJlbCA9IGFmdGVyX3N0YXQoc3RyYXR1bSkpLCBzaXplID0gNSkgKw0KICBsYWJzKHg9ICJWYXJpYWJsZXMiLCB5ID0gIkZyZXF1ZW5jeSIsIGZpbGwgPSAiSm91cm5hbCBDYXRlZ29yeSBBbGxvY2F0ZWQiKSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczIyDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczIyLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczIyLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzMjMNCkJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIHRvdGFsIGNvdW50IG9mIHZpc3VhbGl6YXRpb24gbWV0aG9kcyB1c2VkIGluIG1ldGEtYW5hbHlzZXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlIHRoYXQgc29tZSBtZXRhLWFuYWx5c2VzIG1heSBjb250cmlidXRlIHRvIG11bHRpcGxlIHNlY3Rpb25zIGlmIHRoZSBzdHVkeSBpbnZvbHZlZCB0aGUgdXNlIG9mIG11bHRpcGxlIHZpc3VhbGl6YXRpb24gbWV0aG9kcy4NCmBgYHtyLCBmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0aGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnZpc3VhbGl6YXRpb25fY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKHZpc3VhbGl6YXRpb25fbWV0aG9kLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KHZpc3VhbGl6YXRpb25fbWV0aG9kKSAlPiUNCiAgZmlsdGVyKHZpc3VhbGl6YXRpb25fbWV0aG9kICE9ICJOQSIpICU+JQ0KICAgIGdyb3VwX2J5KHZpc3VhbGl6YXRpb25fbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCnZpc3VhbGl6YXRpb25fcGN0IDwtIHZpc3VhbGl6YXRpb25fY291bnQgJT4lDQogIG11dGF0ZShwcm9wb3J0aW9uID0gbiAvIHN1bSh2aXN1YWxpemF0aW9uX2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24gKiAxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90DQpmaWdzMjMgPC0gdmlzdWFsaXphdGlvbl9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIodmlzdWFsaXphdGlvbl9tZXRob2QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcih2aXN1YWxpemF0aW9uX21ldGhvZCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHZpc3VhbGl6YXRpb25fcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAwKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KHZpc3VhbGl6YXRpb25fY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczIzDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczIzLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczIzLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KDQojIyBGaWd1cmUgczI0DQpBbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgdmlzdWFsaXphdGlvbiBtZXRob2QuIA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCnZpenVhbGl6YXRpb25fYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3ModmlzdWFsaXphdGlvbl9tZXRob2QsIHNlcCA9ICIsXFxzKyIpICU+JQ0KICAgIGZpbHRlcighaXMubmEodmlzdWFsaXphdGlvbl9tZXRob2QpKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBzZXAgPSAiL1xccysiKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgdmlzdWFsaXphdGlvbl9tZXRob2QpICU+JSANCiAgICBjb3VudCh2aXN1YWxpemF0aW9uX21ldGhvZCwgSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpICU+JSANCiAgICBzdW1tYXJpc2UoZnJlcSA9IG4oKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lIA0KICAgIGdyb3VwX2J5KHZpc3VhbGl6YXRpb25fbWV0aG9kKSANCg0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZmlnczI0IDwtIHZpenVhbGl6YXRpb25fYWxsdXZpYWwgJT4lIA0KZ2dwbG90KGFlcyh5ID0gZnJlcSAsYXhpczEgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgYXhpczIgPSB2aXN1YWxpemF0aW9uX21ldGhvZCkpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSBjKCJKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSIsICJST0IgQXNzZXNzbWVudCBNZXRob2QiKSwgZXhwYW5kID0gYyguMDUsIC4wNSkpICsNCiAgeGxhYigiVmFyaWFibGVzIikgKw0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQpKSArDQogIGdlb21fc3RyYXR1bSh3aWR0aCA9IDEvNCwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIHNpemUgPSA2KSArDQogIGxhYnMoeD0gIlZhcmlhYmxlcyIsIHkgPSAiRnJlcXVlbmN5IiwgZmlsbCA9ICJKb3VybmFsIENhdGVnb3J5IEFsbG9jYXRlZCIpICsNCiAgdGhlbWVfc3VwcGwoKQ0KDQpmaWdzMjQNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjQucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjQuanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzMjUNCkJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIHRvdGFsIGNvdW50IG9mIHJlcG9ydGluZyBndWlkZWxpbmVzIHVzZWQgaW4gbWV0YS1hbmFseXNlcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIE5vdGUgdGhhdCBzb21lIG1ldGEtYW5hbHlzZXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVkIHRoZSB1c2Ugb2YgbXVsdGlwbGUgcmVwb3J0aW5nIGd1aWRlbGluZXMuDQpgYGB7ciwgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdGhlIHRvdGFsIGNvdW50IGZvciBlYWNoIGNhdGVnb3J5DQpyZXBvcnRpbmdfZ3VpZGVfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgc2VwID0gIixcXHMrIikgJT4lIA0KICBjb3VudChyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpICU+JQ0KICBmaWx0ZXIocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlICE9ICJOQSIpICU+JQ0KICAgIGdyb3VwX2J5KHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhbGN1bGF0ZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIGZvciBlYWNoIGNhdGVnb3J5DQpyZXBvcnRpbmdfZ3VpZGVfcGN0IDwtIHJlcG9ydGluZ19ndWlkZV9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuIC8gc3VtKHJlcG9ydGluZ19ndWlkZV9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uICogMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdA0KZmlnczI1IDwtIHJlcG9ydGluZ19ndWlkZV9jb3VudCAlPiUNCiAgZ2dwbG90KGFlcyh4ID0gbiwgeSA9IHJlb3JkZXIocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlLCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlLCBuKSksIGhqdXN0ID0gMC41LCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChkYXRhID0gcmVwb3J0aW5nX2d1aWRlX3BjdCwgYWVzKGxhYmVsID0gcGFzdGUwKCIoIiwgcm91bmQocGVyY2VudGFnZSwgMCksICIlKSIpLCB4ID0gbiksIA0KICAgICAgICAgICAgaGp1c3QgPSAtMC4xLCBzaXplID0gNiwgY29sb3IgPSAiYmxhY2siLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBzY2FsZV9maWxsX2lkZW50aXR5KGd1aWRlID0gIm5vbmUiKSArDQogIHNjYWxlX3hfY29udGludW91cyhuYW1lID0gIkFydGljbGUgQ291bnQiLCBleHBhbmQgPSBjKDAsIDApLCBsaW1pdHMgPSBjKDAsIG1heChyZXBvcnRpbmdfZ3VpZGVfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczI1DQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczI1LnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczI1LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KDQojIyBGaWd1cmUgczI2DQpBbiBhbGx1dmlhbCBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBKb3VybmFsIENpdGF0aW9uIFJlcG9ydCBDYXRlZ29yeSBhbmQgcmVwb3J0aW5nIGd1aWRlbGluZSB1c2VkIA0KYGBge3IsIGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRGF0YSBUcmFuc2Zvcm1hdGlvbiANCnJlcG9ydGluZ19zdGFuZGFyZHNfYWxsdXZpYWwgPC0gc2QgJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgICBzZXBhcmF0ZV9yb3dzKEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBzZXAgPSAiL1xccysiKSAlPiUNCiAgICBmaWx0ZXIoIWdyZXBsKCJubyBjYXRlZ29yeSBmb3VuZCIsIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCBpZ25vcmUuY2FzZSA9IFRSVUUpKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYShyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUpKSAlPiUNCiAgICBncm91cF9ieShKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCwgcmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSAlPiUgDQogICAgY291bnQocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlLCBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkgJT4lIA0KICAgIHN1bW1hcmlzZShmcmVxID0gbigpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUgDQogICAgZ3JvdXBfYnkocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKQ0KDQojIENyZWF0ZSB0aGUgQWxsdXZpYWwgcGxvdA0KZmlnczI2IDwtIHJlcG9ydGluZ19zdGFuZGFyZHNfYWxsdXZpYWwgJT4lIA0KZ2dwbG90KCBhZXMoeSA9IGZyZXEgLGF4aXMxID0gSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQsIGF4aXMyID0gcmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIkpvdXJuYWwgQ2l0YXRpb24gUmVwb3J0IENhdGVnb3J5IiwgIlJlcG9ydGluZyBTdGFuZGFyZHMgVHlwZSIpLCBleHBhbmQgPSBjKC4wNSwgLjA1KSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIGdlb21fYWxsdXZpdW0oYWVzKGZpbGwgPSBKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS8zLjUsIGZpbGwgPSAid2hpdGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh4PSAiVmFyaWFibGVzIiwgeSA9ICJGcmVxdWVuY3kiLCBmaWxsID0gIkpvdXJuYWwgQ2F0ZWdvcnkgQWxsb2NhdGVkIikgKw0KICBnZW9tX3RleHQoc3RhdCA9ICJzdHJhdHVtIiwgYWVzKGxhYmVsID0gYWZ0ZXJfc3RhdChzdHJhdHVtKSksIHNpemUgPSA2KSArDQogIHRoZW1lX3N1cHBsKCkNCg0KZmlnczI2DQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczI2LnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczI2LmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KDQoNCiMjIEZpZ3VyZSAyDQpBIGNpcmN1bGFyIHRyZWVtYXAgc2hvd2luZyB0aGUgY291bnRzIG9mIGVhY2ggbWV0aG9kb2xvZ2ljYWwgaXRlbSBpbiBleGlzaXRuZyBtZXRhLWFuYWx5c2lzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcw0KYGBge3IsIGZpZy53aWR0aD0yMSwgZmlnLmhlaWdodD0xNX0NCiMgR3JvdXBpbmcgIk1lZGxpbmUiIGFuZCAiUHVibWVkIiB1bmRlciAiUHViTWVkIiBhbmQgc3VtbWluZyB0aGUgY291bnRzDQpkYXRhYmFzZV9jb3VudCA8LSBkYXRhYmFzZV9jb3VudCAlPiUNCiAgbXV0YXRlKGRhdGFiYXNlX3NlYXJjaCA9IGlmX2Vsc2UoZGF0YWJhc2Vfc2VhcmNoICVpbiUgYygiTWVkbGluZSIsICJQdWJtZWQiKSwgIlB1Yk1lZCIsIGRhdGFiYXNlX3NlYXJjaCkpICU+JQ0KICBncm91cF9ieShkYXRhYmFzZV9zZWFyY2gpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBTcGxpdHRpbmcsIGdyb3VwaW5nLCBhbmQgc3VtbWluZyBkaWZmZXJlbnQgY2F0ZWdvcmllcyBvZiBlZmZlY3Qgc2l6ZXMNCmVmZmVjdHNpemVfY291bnQgPC0gc2QgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKGVmZmVjdF9zaXplLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIGNvdW50KGVmZmVjdF9zaXplKSAlPiUNCiAgZmlsdGVyKGVmZmVjdF9zaXplICE9ICJOQSIpICU+JQ0KICBncm91cF9ieShlZmZlY3Rfc2l6ZSkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQplZmZlY3RzaXplX2NvdW50IDwtIGVmZmVjdHNpemVfY291bnQgJT4lIA0KICBtdXRhdGUoZWZmZWN0X3NpemUgPSBpZl9lbHNlKGVmZmVjdF9zaXplICVpbiUgYygiQmV0YSByZWdyZXNzaW9uIGNvZWZmaWNpZW50IiwgImNvcnJlbGF0aW9uIGNvZWZmaWNpZW50IiksICJDb3JyZWxhdGlvbiIsIGVmZmVjdF9zaXplKSkgJT4lIA0KICBtdXRhdGUoZWZmZWN0X3NpemUgPSBpZl9lbHNlKGVmZmVjdF9zaXplICVpbiUgYygib2RkcyByYXRpbyIsICJyZXNwb25zZSByYXRpbyIsICJTTUQgKHN0YW5kYXJkaXplZCBtZWFuIGRpZmZlcmVuY2UpIiwgImxuUFIgKGxvZyBwYXJ0aXRpb25pbmcgcmF0aW8pIiwgImxuT1IgKGxvZyBvZGRzIHJhdGlvKSIsICJyYXRpbyBvZiBtZWFucyIsICJJblJSIChsb2cgcmVzcG9uc2UgcmF0aW8pIiksICJNZWFuIGRpZmYiLCBlZmZlY3Rfc2l6ZSkpICU+JSANCiAgbXV0YXRlKGVmZmVjdF9zaXplID0gaWZfZWxzZShlZmZlY3Rfc2l6ZSAlaW4lIGMoInJpc2sgcmF0aW8iKSwgIjJ4MiIsIGVmZmVjdF9zaXplKSkgJT4lIA0KICBtdXRhdGUoZWZmZWN0X3NpemUgPSBpZl9lbHNlKGVmZmVjdF9zaXplICVpbiUgYygicmF3IHdlaWdodCIsICJ0cmFuc2ZlciByYXRlIiwgImdlb21ldHJpYyBtZWFuIiwgIm1hdGVybmFsIHRyYW5zZmVyIHJhdGlvIiwgInN0YW5kYXJkaXplZCBtb3J0YWxpdHkgcmF0ZSIsICJUcmFuc2ZlciByYXRlIiwgInotc2NvcmUiLCAibG5DVlIgKGxvZyBjb2VmZmljaWVudCB2YXJpYXRpb24gcmF0aW8pIiksICJPdGhlciBFUyIsIGVmZmVjdF9zaXplKSkgJT4lIA0KICBncm91cF9ieShlZmZlY3Rfc2l6ZSkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIENhdGVnb3JpemluZyBzb2Z0d2FyZSBhcyBlaXRoZXIgIkNvZGUtYmFzZWQgc29mdHdhcmUiIG9yICJHVUkiIGFuZCBzdW1taW5nIHRoZSBjb3VudHMNCnNvZnR3YXJlX2NvdW50IDwtIHNvZnR3YXJlX2NvdW50ICU+JQ0KICBtdXRhdGUoc29mdHdhcmVfYW5hbHlzaXMgPSBpZl9lbHNlKHNvZnR3YXJlX2FuYWx5c2lzICVpbiUgYygiU3RhdGEiLCAiUiIpLCAiQ29kZS1iYXNlZCIsIHNvZnR3YXJlX2FuYWx5c2lzKSkgJT4lDQogIG11dGF0ZShzb2Z0d2FyZV9hbmFseXNpcyA9IGlmX2Vsc2Uoc29mdHdhcmVfYW5hbHlzaXMgJWluJSBjKCJDTUFTIiwgIkV4Y2VsIiwgIlJldk1hbiIsICJTQVMiLCAiWExTVEFUIiksICJHVUkiLCBzb2Z0d2FyZV9hbmFseXNpcykpICU+JSANCiAgZ3JvdXBfYnkoc29mdHdhcmVfYW5hbHlzaXMpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBHcm91cGluZyBoZXRlcm9nZW5laXR5IGFzc2Vzc21lbnQgbWV0aG9kcyBhbmQgc3VtbWluZyB0aGUgY291bnRzDQpoZXRlcm9nZW5laXR5X2NvdW50IDwtIGhldGVyb2dlbmVpdHlfY291bnQgJT4lIA0KICBtdXRhdGUoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCA9IGlmX2Vsc2UoaGV0ZXJvZ2VuZWl0eV9hc3Nlc3NtZW50X21ldGhvZCAlaW4lIGMoIlRhdSBzcXVhcmUiKSwgIkkgc3F1YXJlZCIsIGhldGVyb2dlbmVpdHlfYXNzZXNzbWVudF9tZXRob2QpKSAlPiUgDQogIG11dGF0ZShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kID0gaWZfZWxzZShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kICVpbiUgYygiQ2hpIHNxdWFyZSIpLCAiUSBzdGF0aXN0aWMiLCBoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSkgJT4lIA0KICBncm91cF9ieShoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgR3JvdXBpbmcgYmlhcyBhc3Nlc3NtZW50IG1ldGhvZHMgd2l0aCBjb3VudCA8PSAzIHVuZGVyICJPdGhlciBCQSIgYW5kIHN1bW1pbmcgdGhlIGNvdW50cw0KYmlhc19tZXRob2RfY291bnQgPC0gYmlhc19tZXRob2RfY291bnQgJT4lIA0KICBtdXRhdGUoYmlhc19hc3Nlc3NtZW50X21ldGhvZCA9IGlmX2Vsc2UoYmlhc19hc3Nlc3NtZW50X21ldGhvZCAlaW4lIGMoIkVnZ2VyJ3MgcmVncmVzc2lvbiB0ZXN0IiwgIkZhaWwgc2FmZSIsICJCZWdnJ3MgdGVzdCIsICJLZW5kYWxsJ3MgdGF1IHN0YXRpc3RpYyIpLCJCaWFzIHN0YXRpc3RpY2FsIHRlc3QiLCBiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSkgJT4lIA0KICBncm91cF9ieShiaWFzX2Fzc2Vzc21lbnRfbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgR3JvdXBpbmcgc2Vuc2l0aXZpdHkgYW5hbHlzaXMgbWV0aG9kcyBhbmQgc3VtbWluZyB0aGUgY291bnRzDQpzZW5zaXRpdml0eV9jb3VudCA8LSAgc2Vuc2l0aXZpdHlfY291bnQgJT4lICANCiAgbXV0YXRlKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCA9IGlmZWxzZShuPD0gOCwgIk90aGVyIHNlbnNpdGl2aXR5IGFuYWx5c2lzIiwgYXMuY2hhcmFjdGVyKHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCkpKSAlPiUgDQogIGdyb3VwX2J5KHNlbnNpdGl2aXR5X2FuYWx5c2lzX21ldGhvZCkgJT4lDQogIHN1bW1hcmlzZShuID0gc3VtKG4pKQ0KDQojIEdyb3VwaW5nIHJpc2sgb2YgYmlhcyBhc3Nlc3NtZW50IG1ldGhvZHMgd2l0aCBjb3VudCA8PSAzIHVuZGVyICJPdGhlciBST0IiIGFuZCBzdW1taW5nIHRoZSBjb3VudHMNCnJvYl9tZXRob2RfY291bnQgPC0gIHJvYl9tZXRob2RfY291bnQgJT4lICANCiAgbXV0YXRlKHJvYl9hc3Nlc3NtZW50X21ldGhvZCA9IGlmZWxzZShuPD0gMywgIk90aGVyIFJPQiIsIGFzLmNoYXJhY3Rlcihyb2JfYXNzZXNzbWVudF9tZXRob2QpKSkgJT4lIA0KICBncm91cF9ieShyb2JfYXNzZXNzbWVudF9tZXRob2QpICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBHcm91cGluZyB2aXN1YWxpemF0aW9uIG1ldGhvZHMgd2l0aCBjb3VudCA8PSAzIHVuZGVyICJPdGhlciBWaXoiIGFuZCBzdW1taW5nIHRoZSBjb3VudHMNCnZpc3VhbGl6YXRpb25fY291bnQgPC0gdmlzdWFsaXphdGlvbl9jb3VudCAlPiUgDQogIG11dGF0ZSh2aXN1YWxpemF0aW9uX21ldGhvZCA9IGlmZWxzZShuPD0gMywgIk90aGVyIFZpeiIsIGFzLmNoYXJhY3Rlcih2aXN1YWxpemF0aW9uX21ldGhvZCkpKSAlPiUgDQogIGdyb3VwX2J5KHZpc3VhbGl6YXRpb25fbWV0aG9kKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgR3JvdXBpbmcgcmVwb3J0aW5nIHN0YW5kYXJkcyB0eXBlcyB3aXRoIGNvdW50IDw9IDIgdW5kZXIgIk90aGVyIGd1aWRlbGluZSIgYW5kIHN1bW1pbmcgdGhlIGNvdW50cw0KcmVwb3J0aW5nX2d1aWRlX2NvdW50IDwtIHJlcG9ydGluZ19ndWlkZV9jb3VudCAlPiUgDQogIG11dGF0ZShyZXBvcnRpbmdfc3RhbmRhcmRzX3R5cGUgPSBpZmVsc2Uobjw9IDIsICJPdGhlciBndWlkZWxpbmUiLCBhcy5jaGFyYWN0ZXIocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSkpICU+JSANCiAgZ3JvdXBfYnkocmVwb3J0aW5nX3N0YW5kYXJkc190eXBlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgR3JvdXBpbmcgYmlhcyBhc3Nlc3NtZW50IHZpc3VhbGl6YXRpb24gdHlwZXMgYW5kIHN1bW1pbmcgdGhlIGNvdW50cw0KYmlhc192aXN1YWxpemF0aW9uX2NvdW50IDwtIGJpYXNfdmlzdWFsaXphdGlvbl9jb3VudCAlPiUgDQogIG11dGF0ZShiaWFzX2Fzc2Vzc21lbnRfdmlzdWFsaXphdGlvbiA9IGlmX2Vsc2UoYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24gJWluJSBjKCJEb2kgcGxvdCIsICJUcmltIGFuZCBmaWxsIiwgIkZ1bm5lbCBwbG90IiwgIkdhbGJyYWl0aCBwbG90IiksICJCaWFzIHZpc3VhbGl6YXRpb24iLCBiaWFzX2Fzc2Vzc21lbnRfdmlzdWFsaXphdGlvbikpICU+JSANCiAgZ3JvdXBfYnkoYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24pICU+JQ0KICBzdW1tYXJpc2UobiA9IHN1bShuKSkNCg0KIyBDb21iaW5lIHRoZSBkYXRhIGZyYW1lcyBhbmQgdW5pdGUgdGhlIG1ldGhvZG9sb2d5IHR5cGVzDQpkZiA8LSBiaW5kX3Jvd3MoDQogIGRhdGFiYXNlX2NvdW50ICU+JSBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICdEYXRhYmFzZSBTZWFyY2gnKSwNCiAgZWZmZWN0c2l6ZV9jb3VudCAlPiUgbXV0YXRlKG1ldGhvZG9sb2d5X3R5cGUgPSAnRWZmZWN0IFNpemUnKSwNCiAgc29mdHdhcmVfY291bnQgJT4lICBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICJTb2Z0d2FyZSIpLA0KICBoZXRlcm9nZW5laXR5X2NvdW50ICU+JSBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICJIZXRlcm9nZW5laXR5IiksDQogIHNlbnNpdGl2aXR5X2NvdW50ICU+JSBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICJTZW5zaXRpdml0eV9BbmFseXNpcyIpLA0KICBiaWFzX21ldGhvZF9jb3VudCAlPiUgIG11dGF0ZShtZXRob2RvbG9neV90eXBlID0gIkJpYXMgQXNzZXNzbWVudCIpLA0KICByb2JfbWV0aG9kX2NvdW50ICU+JSBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICJSaXNrICBvZiBCaWFzIiksIA0KICMgdmlzdWFsaXphdGlvbl9jb3VudCAlPiUgbXV0YXRlKG1ldGhvZG9sb2d5X3R5cGUgPSAiVmlzdWFsaXphdGlvbiIpLA0KICByZXBvcnRpbmdfZ3VpZGVfY291bnQgJT4lICBtdXRhdGUobWV0aG9kb2xvZ3lfdHlwZSA9ICJSZXBvcnRpbmcgR3VpZGUiKSwNCiAgYmlhc192aXN1YWxpemF0aW9uX2NvdW50ICU+JSAgbXV0YXRlKG1ldGhvZG9sb2d5X3R5cGUgPSAiQmlhcyBBc3Nlc3NtZW50IikNCikgJT4lIA0KIHVuaXRlKG1ldGhvZG9sb2d5X3R5cGVfc3BlY2lmaWMsIA0KICAgICAgIGRhdGFiYXNlX3NlYXJjaCwgDQogICAgICAgZWZmZWN0X3NpemUsICANCiAgICAgICBzb2Z0d2FyZV9hbmFseXNpcywNCiAgICAgICBoZXRlcm9nZW5laXR5X2Fzc2Vzc21lbnRfbWV0aG9kLCANCiAgICAgICBzZW5zaXRpdml0eV9hbmFseXNpc19tZXRob2QsIA0KICAgICAgIGJpYXNfYXNzZXNzbWVudF9tZXRob2QsDQogICAgICAgcm9iX2Fzc2Vzc21lbnRfbWV0aG9kLCANCiAgICAgICMgdmlzdWFsaXphdGlvbl9tZXRob2QsIA0KICAgICAgIHJlcG9ydGluZ19zdGFuZGFyZHNfdHlwZSwgDQogICAgICAgYmlhc19hc3Nlc3NtZW50X3Zpc3VhbGl6YXRpb24sDQogICAgICAgcmVtb3ZlID0gVFJVRSwgbmEucm0gPSBUUlVFKQ0KDQojIFByZXBhcmluZyB0aGUgZWRnZXMgZGF0YWZyYW1lIGZvciBjcmVhdGluZyB0aGUgZ3JhcGgNCmVkZ2VzIDwtIGRmICU+JQ0KICByZW5hbWUoZnJvbSA9IG1ldGhvZG9sb2d5X3R5cGUsIHRvID0gbWV0aG9kb2xvZ3lfdHlwZV9zcGVjaWZpYywgc2l6ZSA9IG4pICU+JQ0KICBzZWxlY3QoYyhmcm9tLHRvLHNpemUpKSAlPiUNCiAgYXMuZGF0YS5mcmFtZSgpDQoNCiMgUHJlcGFyaW5nIHRoZSB2ZXJ0aWNlcyBkYXRhZnJhbWUgZm9yIGNyZWF0aW5nIHRoZSBncmFwaA0KdmVydGljZXMgPC0gZGYgICU+JQ0KICByZW5hbWUobmFtZSA9IG1ldGhvZG9sb2d5X3R5cGVfc3BlY2lmaWMsIHNpemUgPSBuKSAlPiUNCiAgc2VsZWN0KGMobmFtZSxzaXplKSkgJT4lDQogIGFzLmRhdGEuZnJhbWUoKQ0KDQojIEFwcGVuZGluZyB1bmlxdWUgJ2Zyb20nIHZhbHVlcyB0byB2ZXJ0aWNlcyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZyBzdW1tZWQgc2l6ZXMNCnZlcnRpY2VzWyhucm93KGVkZ2VzKSsxKToobnJvdyhlZGdlcykrbGVuZ3RoKHVuaXF1ZShlZGdlcyRmcm9tKSkpLDFdIDwtIHVuaXF1ZShlZGdlcyRmcm9tKQ0KTiA8LSBhZ2dyZWdhdGUoZWRnZXMkc2l6ZSwgbGlzdChlZGdlcyRmcm9tKSwgRlVOPXN1bSkNCnZlcnRpY2VzWyhucm93KGVkZ2VzKSsxKToobnJvdyhlZGdlcykrbGVuZ3RoKHVuaXF1ZShlZGdlcyRmcm9tKSkpLDJdIDwtIE4keA0KDQojIENyZWF0aW5nIGEgZ3JhcGggb2JqZWN0IGZyb20gdGhlIGVkZ2VzIGFuZCB2ZXJ0aWNlcyBkYXRhZnJhbWVzDQpteWdyYXBoIDwtIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShlZGdlcywgdmVydGljZXMgPSB2ZXJ0aWNlcykNCg0KIyBQbG90dGluZyB0aGUgZ3JhcGggdXNpbmcgYSAnY2lyY2xlcGFjaycgbGF5b3V0LCBhZGRpbmcgbGFiZWxzIGFuZCBhZGp1c3RpbmcgYWVzdGhldGljcw0KDQpmaWcyIDwtIGdncmFwaChteWdyYXBoLCBsYXlvdXQgPSAnY2lyY2xlcGFjaycsIHdlaWdodCA9IHNpemUpICsgDQogICAgZ2VvbV9ub2RlX2NpcmNsZShhZXMoZmlsbCA9IGFzLmZhY3RvcihkZXB0aCkpLCBjb2xvciA9IE5BKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiIzFiOWU3NyIsICIjODhEMUFEIikpICsgDQogICAgZ2VvbV9ub2RlX3RleHQoYWVzKGxhYmVsID0gbmFtZSwgZmlsdGVyID0gbGVhZiwgc2l6ZSA9IDEwKSwgdmp1c3QgPSAtMC4zLCBmb250ZmFjZSA9ICJib2xkIikgKw0KICAgIGdlb21fbm9kZV90ZXh0KGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHNpemUsICIpIiksIGZpbHRlciA9IGxlYWYsIHNpemUgPSAxMCksIHZqdXN0ID0gMSwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgICB0aGVtZV92b2lkKCkgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgDQoNCmZpZzINCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWcyLnBkZiIpLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWcyLmpwZyIpLCB3aWR0aCA9IDE4LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCg0KIyMgRmlndXJlIDMNClRoZSBhdmVyYWdlIHJlcG9ydGluZyBxdWFsaXR5IGFuZCByaWdvdXIgb2YgbWV0YS1hbmFseXNpcyBhY2NvcmRpbmcgdG8gQ0VFU0FUIDIuMSAoV29vZGNvY2sgZXQgYWwuLCAyMDE0KS4gR29sZCBpcyByZWdhcmQgYXMgdGhlIGhpZ2hlc3Qgc2NvcmUsIGdyZWVuIGlzIHNlY29uZCBoaWdoZXN0IHNjb3JlLCBhbWJlciBpcyBzZWNvbmQtbG93ZXN0IHNjb3JlLCBhbmQgcmVkIGlzIHRoZSBsb3dlc3Qgc2NvcmUuIEFsbCBDRUVTQVQgMi4xIGl0ZW1zIGFsb25nIHdpdGggb3VyIGludGVycHJldGF0aW9uIGFyZSBwcm92aWRlZCBpbiB0aGUgU3VwcGxlbWVudGFyeSBGaWxlIDIuDQpgYGB7ciwgZmlnLndpZHRoPTI1LCBmaWcuaGVpZ2h0PTE1fQ0KIyBTdGFydCB0aGUgZGF0YSBtYW5pcHVsYXRpb24NCnBlcmNlbnRfY2Vlc2F0X3Njb3JlIDwtIHNkICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGF1dGhvcl95ZWFyKSkgJT4lDQogIHNlbGVjdChzdHVkaWVzID0gYXV0aG9yX3llYXIsIHN0YXJ0c193aXRoKCJDRUUiKSkgJT4lDQogIG5hLm9taXQoKSAlPiUNCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtc3R1ZGllcywgbmFtZXNfdG8gPSAicXVlc3Rpb24iLCB2YWx1ZXNfdG8gPSAic2NvcmUiKSAlPiUNCiAgZ3JvdXBfYnkocXVlc3Rpb24sIHNjb3JlKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBtdXRhdGUocGVyY2VudCA9IChuL3N1bShuKSkqMTAwLCANCiAgICAgICAgIGFjcm9zcyhjKHF1ZXN0aW9uLCBzY29yZSksIGFzLmZhY3RvciksDQogICAgICAgICBxdWVzdGlvbiA9IGZjdF9yZWNvZGUocXVlc3Rpb24sIA0KICAgICAgICAgICBgMS4xIEFyZSB0aGUgZWxlbWVudHMgb2YgdGhlIHJldmlldyBxdWVzdGlvbiBjbGVhcj9gID0gIkNFRVNBVDJfMS4xIiwNCiAgICAgICAgICAgYDIuMSBJcyB0aGVyZSBhbiBhLXByaW9yaSBtZXRob2QgcHJvdG9jb2wgZG9jdW1lbnQ/YCA9ICJDRUVTQVQyXzIuMSIsDQogICAgICAgICAgIGAzLjEuIElzIHRoZSBhcHByb2FjaCB0byBzZWFyY2hpbmcgY2xlYXJseSBkZWZpbmVkc3lzdGVtYXRpYyBhbmRcbnRyYW5zcGFyZW50P2AgPSAiQ0VFU0FUMl8zLjEiLA0KICAgICAgICAgICBgMy4yLiBJcyB0aGUgc2VhcmNoIGNvbXByZWhlbnNpdmU/YCA9ICJDRUVTQVQyXzMuMiIsDQogICAgICAgICAgIGA0LjEuIEFyZSBlbGlnaWJpbGl0eSBjcml0ZXJpYSBjbGVhcmx5IGRlZmluZWQ/YCA9ICJDRUVTQVQyXzQuMSIsDQogICAgICAgICAgIGA0LjIuIEFyZSBlbGlnaWJpbGl0eSBjcml0ZXJpYSBjb25zaXN0ZW50bHkgYXBwbGllZCB0byBhbGwgcG90ZW50aWFsbHkgcmVsZXZhbnRcbmFydGljbGVzIGFuZCBzdHVkaWVzIGZvdW5kIGR1cmluZyB0aGUgc2VhcmNoP2AgPSAiQ0VFU0FUMl80LjIiLA0KICAgICAgICAgICBgNC4zLiBBcmUgZWxpZ2liaWxpdHkgZGVjaXNpb25zIHRyYW5zcGFyZW50bHkgcmVwb3J0ZWQ/YCA9ICJDRUVTQVQyXzQuMyIsDQogICAgICAgICAgIGA1LjEuIERvZXMgdGhlIHJldmlldyBjcml0aWNhbGx5IGFwcHJhaXNlIGVhY2ggc3R1ZHk/YCA9ICJDRUVTQVQyXzUuMSIsDQogICAgICAgICAgIGA1LjIuIER1cmluZyBjcml0aWNhbCBhcHByYWlzYWwgd2FzIGFuIGVmZm9ydCBtYWRlIHRvIG1pbmltaXNlXG5zdWJqZWN0aXZpdHk/YCA9ICJDRUVTQVQyXzUuMiIsDQogICAgICAgICAgIGA2LjEuIElzIHRoZSBtZXRob2Qgb2YgZGF0YSBleHRyYWN0aW9uIGZ1bGx5IGRvY3VtZW50ZWQ/YCA9ICJDRUVTQVQyXzYuMSIsDQogICAgICAgICAgIGA2LjIuIEFyZSB0aGUgZXh0cmFjdGVkIGRhdGEgcmVwb3J0ZWQgZm9yIGVhY2ggc3R1ZHk/YCA9ICJDRUVTQVQyXzYuMiIsDQogICAgICAgICAgIGA2LjMuIFdlcmUgZXh0cmFjdGVkIGRhdGEgY3Jvc3MgY2hlY2tlZCBieSBtb3JlIHRoYW4gb25lIHJldmlld2VyP2AgPSAiQ0VFU0FUMl82LjMiLA0KICAgICAgICAgICBgNy4xLiBJcyB0aGUgY2hvaWNlIG9mIHN5bnRoZXNpcyBhcHByb2FjaCBhcHByb3ByaWF0ZT9gID0gIkNFRVNBVDJfNy4xIiwNCiAgICAgICAgICAgYDcuMi4gSXMgYSBzdGF0aXN0aWNhbCBlc3RpbWF0ZSBvZiBwb29sZWQgZWZmZWN0IHByb3ZpZGVkIHRvZ2V0aGVyIHdpdGhcbm1lYXN1cmUgb2YgdmFyaWFuY2UgYW5kIGhldGVyb2dlbmVpdHkgYW1vbmcgc3R1ZGllcz9gID0gIkNFRVNBVDJfNy4yIiwNCiAgICAgICAgICAgYDcuMyBJcyB2YXJpYWJpbGl0eSBpbiB0aGUgc3R1ZHkgZmluZGluZ3MgaW52ZXN0aWdhdGVkIGFuZCBkaXNjdXNzZWQ/YCA9ICJDRUVTQVQyXzcuMyIsDQogICAgICAgICAgIGA4LjEgSGF2ZSB0aGUgYXV0aG9ycyBjb25zaWRlcmVkIGxpbWl0YXRpb25zIGluIHRoZSBzeW50aGVzaXM/YCA9ICJDRUVTQVQyXzguMSIpLA0KICAgICAgICAgcXVlc3Rpb24gPSBmYWN0b3IocXVlc3Rpb24sIGxldmVscyA9IHJldihsZXZlbHMocXVlc3Rpb24pKSksDQogICAgICAgICBzY29yZSA9IGZhY3RvcihzY29yZSwgbGV2ZWxzID0gbGV2ZWxzKHNjb3JlKVtjKDQsMSwzLDIpXSkpDQoNCiMgQ3JlYXRlIENFRVNBVCBwbG90IA0KZmlnMyA8LSBnZ3Bsb3QoZGF0YSA9IHBlcmNlbnRfY2Vlc2F0X3Njb3JlLCBhZXMoeCA9IHF1ZXN0aW9uLCB5ID0gcGVyY2VudCwgZmlsbCA9IHNjb3JlKSkgKw0KICBnZW9tX2NvbCh3aWR0aCA9IDAuNywgcG9zaXRpb24gPSAiZmlsbCIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiksIHBvc2l0aW9uID0gcG9zaXRpb25fZmlsbCh2anVzdCA9IDAuNSksIHNpemUgPSA3LCBmb250ZmFjZSA9ICJib2xkIikgKw0KICBjb29yZF9mbGlwKCkgKw0KICBndWlkZXMoZmlsbCA9IGd1aWRlX2xlZ2VuZChyZXZlcnNlID0gVFJVRSkpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI0ZGMDAwMCIsIiNGRkQ3MDAiLCIjMDA4MDAwIiwgIiNEQUE1MjAiKSwgbmFtZSA9ICJTY29yZToiKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIA0KICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksIA0KICAgICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICB5bGFiKCJQZXJjZW50YWdlIikgKyANCiAgeGxhYigiQ0VFU0FUIFF1ZXN0aW9uIikNCg0KZmlnMw0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzMucGRmIiksIHdpZHRoID0gMjUsIGhlaWdodCA9IDE1LCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWczLmpwZyIpLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCmBgYA0KDQojIE9iamVjdGl2ZSAyIA0KVG8gZXhwbG9yZSB0aGUgdmFyaW91cyBjaGFyYWN0ZXJpc3RpY3Mgb2YgdGhlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMgbGl0ZXJhdHVyZSBzdWNoIGFzIHRoZSBwZXN0aWNpZGVzIHVzZWQsIHRoZSBpbXBhY3RzIGVsaWNpdGVkIGluIHJlc3BvbnNlIGFuZCB0aGUgc3ViamVjdHMgdGhhdCB3ZXJlIGludmVzdGlnYXRlZC4NCg0KIyMgRmlndXJlIHMyNw0KQSBiYXIgcGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCB0b3RhbCBjb3VudCBvZiB0b3RhbCBvZiBwZXN0aWNpZGVzIGludmVzdGlnYXRlIGluIG1ldGEtYW5hbHlzaXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlOiBzb21lIG1ldGEtYW5hbHlzaXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVzIG11bHRpcGxlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIEZpbHRlcmVkIGZvciBwZXN0aWNpZGUgY291bnRzIGdyZWF0ZXIgdGhhbiA2LiANCmBgYHtyLGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgRnVuY3Rpb24gdG8gcmVwbGFjZSBsb25nIE9DUCBuYW1lcyB3aXRoIGFiYnJldmlhdGlvbnMNCnJlcGxhY2Vfb2NwIDwtIGZ1bmN0aW9uKGRmKSB7DQogIGRmICU+JSANCiAgICBtdXRhdGUob2NwID0gY2FzZV93aGVuKA0KICAgICAgIyBIQ0ggcmVsYXRlZCByZXBsYWNlbWVudHMNCiAgICAgIGdyZXBsKCJIZXhhY2hsb3JvY3ljbG9oZXhhbmUgXFwoSENIXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkhDSCIsDQogICAgICBncmVwbCgiYWxwaGEtSGV4YWNobG9yb2N5Y2xvaGV4YW5lIFxcKGFscGhhLUhDSFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICLOsSAtIEhDSCIsDQogICAgICBncmVwbCgiYmV0YS1IZXhhY2hsb3JvY3ljbG9oZXhhbmUgXFwoYmV0YS1IQ0hcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAizrIgLSBIQ0giLA0KICAgICAgZ3JlcGwoImdhbW1hLUhleGFjaGxvcm9jeWNsb2hleGFuZSBcXChnYW1tYS1IQ0hcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiTGluZGFuZSIsDQogICAgICAjIEREVCByZWxhdGVkIHJlcGxhY2VtZW50cw0KICAgICAgZ3JlcGwoIkRpY2hsb3JvZGlwaGVueWx0cmljaGxvcm9ldGhhbmUgXFwoRERUXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkREVCIsDQogICAgICBncmVwbCgicCxwLURpY2hsb3JvZGlwaGVueWx0cmljaGxvcm9ldGhhbmUgXFwocCxwLUREVFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJwLHAtRERUIiwNCiAgICAgIGdyZXBsKCJvLHAtRGljaGxvcm9kaXBoZW55bHRyaWNobG9yb2V0aGFuZSBcXChvLHAtRERUXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIm8scC1ERFQiLA0KICAgICAgIyBEREQgcmVsYXRlZCByZXBsYWNlbWVudHMNCiAgICAgIGdyZXBsKCJEaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGhhbmUgXFwoREREXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERCIsDQogICAgICBncmVwbCgicCxwLURpY2hsb3JvZGlwaGVueWxkaWNobG9yb2V0aGFuZSBcXChwLHAtREREXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gInAscC1EREQiLA0KICAgICAgZ3JlcGwoIm8scC1EaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGhhbmUgXFwobyxwLURERFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJvLHAtREREIiwNCiAgICAgICMgRERFIHJlbGF0ZWQgcmVwbGFjZW1lbnRzDQogICAgICBncmVwbCgiRGljaGxvcm9kaXBoZW55bGRpY2hsb3JvZXRoeWxlbmUgXFwoRERFXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERSIsDQogICAgICBncmVwbCgicCxwLURpY2hsb3JvZGlwaGVueWxkaWNobG9yb2V0aHlsZW5lIFxcKHAscC1EREVcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAicCxwLURERSIsDQogICAgICBncmVwbCgibyxwLURpY2hsb3JvZGlwaGVueWxkaWNobG9yb2V0aHlsZW5lIFxcKG8scC1EREVcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAibyxwLURERSIsDQogICAgICBUUlVFIH4gb2NwICAjIG5vIGNoYW5nZSBmb3IgYW55IG90aGVycw0KICAgICkpDQp9DQojIFRyYW5zZm9ybSB0aGUgZGF0YSANCm9jcF9jb3VudCA8LQ0KICBvY3AgJT4lIA0KICBzZXBhcmF0ZV9yb3dzKG9jcCwgc2VwID0gIixcXHMrIikgJT4lIA0KICByZXBsYWNlX29jcCAlPiUgDQogIGNvdW50KG9jcCkgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKG9jcCkpICU+JSAjIGZpbHRlciBvdXQgTkEgDQogIGFycmFuZ2UoZGVzYyhuKSkgJT4lIA0KICBtdXRhdGUob2NwID0gaWZlbHNlKG4gPD0gNiwgIm90aGVyIE9DUCIsIGFzLmNoYXJhY3RlcihvY3ApKSkgJT4lIA0KIyBPdGhlciBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzIGluY2x1ZGU6IHRveGFwaGVuZSAobj02KSwgTWV0aG94eWNobG9yIChuPTYpLCBwLHAtREREIChuPTUpLCBvLHAtREREIChuPTUpLCBjaXMtQ2hsb3JkYW5lIChuPTUpLCB0cmFucz1DaGxvcmRhbmUgKG49NCksIEVuZG9zdWxmYW4gSUkgKG49NCksIEVuZG9zdWxmYW4gKG49MyksbyxwLURERCAobj0zKSwgY2lzLU5vbmFjaGxvciAobj0zKSB5LUNobG9yZGFuZSAobj0yKSwgQ2hsb3JvcGhlbm9sIChuPTIpLCBiZXRhLUJIQyAobj0yKSwgYWxwaGEtQ2hsb3JkYW5lIChuPTIpLCBUQ0REIChuPTEpLCBOb25hY2hsb3JlIChuPTEpLCBFbmRyaW4ga2V0b25lIChuPTEpLCBFbmRyaW4gQWxkZWh5ZGUgKG49MSksIEVuZG9zdWxmYW4gc3VsZmF0ZSAobj0xKSwgRGljb2ZvbCAobj0xKSwgZGVsdGEtSENIIChuPTEpLCBkZWx0YS1CSEMgKG49MSksIERERCAobj0xKSwgY2lzLUhlcHRhY2hsb3IgKG49MSksIGFscGhhLUJIQyAobj0xKS4NCiAgZ3JvdXBfYnkob2NwKSAlPiUgDQogIHN1bW1hcmlzZShuID1zdW0obikpDQoNCiMgQ2FsY3VsYXRlIHRoZSBwcm9wb3J0aW9uIGFuZCBwZXJjZW50YWdlIG9mIGVhY2ggT0NQDQpvY3BfcGN0IDwtIG9jcF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShvY3BfY291bnQkbiksDQogICAgICAgICBwZXJjZW50YWdlID0gcHJvcG9ydGlvbioxMDApDQoNCiMgQ3JlYXRlIHRoZSBjb3VudCBwbG90IGZvciBPQ1BzDQpmaWdzMjcgPC0gb2NwX2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihvY3AsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjgsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKG9jcCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IG9jcF9wY3QsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLSAwLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KG9jcF9jb3VudCRuKSoxLjIpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICAgICAgICApDQoNCmZpZ3MyNw0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyNy5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyNy5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHMyOA0KQSBiYXIgcGxvdCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGFuZCB0b3RhbCBjb3VudCBvZiB0b3RhbCBvZiBzdWJqZWN0cyBpbnZlc3RpZ2F0ZSBpbiBtZXRhLWFuYWx5c2lzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gTm90ZTogc29tZSBtZXRhLWFuYWx5c2lzIG1heSBjb250cmlidXRlIHRvIG11bHRpcGxlIHNlY3Rpb25zIGlmIHRoZSBzdHVkeSBpbnZvbHZlcyBtdWx0aXBsZSBzdWJqZWN0cw0KYGBge3IsZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCnN1YmplY3RfY291bnQgPC0gDQogIHN1YiAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhzdWJqZWN0LCBzZXAgPSAiLFxccysiKSAlPiUgDQogICAgY291bnQoc3ViamVjdCkNCg0KIyBDYWxjdWxhdGUgcHJvcG9ydGlvbiBhbmQgcGVyY2VudGFnZSBmb3IgZWFjaCBjYXRlZ29yeQ0Kc3ViamVjdF9wY3QgPC0gc3ViamVjdF9jb3VudCAlPiUNCiAgbXV0YXRlKHByb3BvcnRpb24gPSBuL3N1bShzdWJqZWN0X2NvdW50JG4pLA0KICAgICAgICAgcGVyY2VudGFnZSA9IHByb3BvcnRpb24qMTAwKQ0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdCBmb3Igc3ViamVjdHMNCmZpZ3MyOCA8LSBzdWJqZWN0X2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihzdWJqZWN0LCBuKSwgZmlsbCA9ICIjMWI5ZTc3IikpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHdpZHRoID0gMC44ICwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG4sIHggPSBuIC8gMiwgeSA9IHJlb3JkZXIoc3ViamVjdCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDcsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IHN1YmplY3RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KHN1YmplY3RfY291bnQkbikqMS4xKSkgKw0KICBsYWJzKHkgPSBOVUxMKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIGF4aXMubGluZS54ID0gZWxlbWVudF9saW5lKGNvbG9yID0gImdyYXkiLCBzaXplID0gMC41KSwNCiAgICAgICAgYXhpcy5saW5lLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSINCiAgICAgICAgKQ0KDQpmaWdzMjgNCg0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjgucGRmIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMjguanBnIiksIHdpZHRoID0gMTYsIGhlaWdodCA9IDEwLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzMjkgDQpBIGJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIHRvdGFsIGNvdW50IG9mIHRvdGFsIG9mIHN1YmplY3RzIGludmVzdGlnYXRlIGluIG1ldGEtYW5hbHlzaXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBOb3RlOiBzb21lIG1ldGEtYW5hbHlzaXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVzIG11bHRpcGxlIHN1YmplY3RzLiBGaWx0ZXJlZCBmb3IgaW1wYWN0IGNvdW50cyBncmVhdGVyIHRoYW4gMS4gDQpgYGB7cixmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQojIENhbGN1bGF0ZSB0b3RhbCBjb3VudCBmb3IgZWFjaCBjYXRlZ29yeQ0KaW1wYWN0X2NvdW50IDwtIA0KICBpbSAlPiUgDQogICAgc2VwYXJhdGVfcm93cyhpbXBhY3QsIHNlcCA9ICIsXFxzKyIpICU+JSANCiAgICBjb3VudChpbXBhY3QpICU+JSANCiAgZmlsdGVyKGltcGFjdCAhPSAiTkEiKSAlPiUNCiAgbXV0YXRlKGltcGFjdCA9IGlmZWxzZShuPD0gMSwgIm90aGVyIiwgYXMuY2hhcmFjdGVyKGltcGFjdCkpKSAlPiUgDQogICAgZ3JvdXBfYnkoaW1wYWN0KSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmltcGFjdF9wY3QgPC0gaW1wYWN0X2NvdW50ICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKGltcGFjdF9jb3VudCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KIyBDcmVhdGUgdGhlIGNvdW50IHBsb3QgZm9yIGltcGFjdHMgDQpmaWdzMjkgPC0gaW1wYWN0X2NvdW50ICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBuLCB5ID0gcmVvcmRlcihpbXBhY3QsIG4pLCBmaWxsID0gIiMxYjllNzciKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5Iiwgd2lkdGggPSAwLjggLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsID0gbiwgeCA9IG4gLyAyLCB5ID0gcmVvcmRlcihpbXBhY3QsIG4pKSwgaGp1c3QgPSAwLjUsIHNpemUgPSA3LCBjb2xvciA9ICJibGFjayIpICsNCiAgZ2VvbV90ZXh0KGRhdGEgPSBpbXBhY3RfcGN0LCBhZXMobGFiZWwgPSBwYXN0ZTAoIigiLCByb3VuZChwZXJjZW50YWdlLCAxKSwgIiUpIiksIHggPSBuKSwgDQogICAgICAgICAgICBoanVzdCA9IC0wLjEsIHNpemUgPSA2LCBjb2xvciA9ICJibGFjayIsIGZvbnRmYWNlID0gImJvbGQiKSArDQogIHNjYWxlX2ZpbGxfaWRlbnRpdHkoZ3VpZGUgPSAibm9uZSIpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWUgPSAiQXJ0aWNsZSBDb3VudCIsIGV4cGFuZCA9IGMoMCwgMCksIGxpbWl0cyA9IGMoMCwgbWF4KGltcGFjdF9jb3VudCRuKSoxLjEpKSArDQogIGxhYnMoeSA9IE5VTEwpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgYXhpcy5saW5lLnggPSBlbGVtZW50X2xpbmUoY29sb3IgPSAiZ3JheSIsIHNpemUgPSAwLjUpLA0KICAgICAgICBheGlzLmxpbmUueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aWNrcy54ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIg0KICAgICAgICApDQoNCmZpZ3MyOQ0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyOS5wZGYiKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3MyOS5qcGciKSwgd2lkdGggPSAxNiwgaGVpZ2h0ID0gMTAsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQoNCmBgYA0KDQojIyBGaWd1cmUgczMwDQpBIGJhciBwbG90IHNob3dpbmcgdGhlIHBlcmNlbnRhZ2UgYW5kIHRvdGFsIGNvdW50IG9mIHRvdGFsIG9mIGltcGFjdCBjYXRlZ29yaWVzIGludmVzdGlnYXRlZCBpbiBtZXRhLWFuYWx5c2lzIGludmVzdGlnYXRpbmcgdGhlIGltcGFjdHMgb2Ygb3JnYW5vY2hsb3JpbmUgcGVzdGljaWRlcy4gDQpOb3RlOiBzb21lIG1ldGEtYW5hbHlzaXMgbWF5IGNvbnRyaWJ1dGUgdG8gbXVsdGlwbGUgc2VjdGlvbnMgaWYgdGhlIHN0dWR5IGludm9sdmVzIG11bHRpcGxlIGltcGFjdHMNCmBgYHtyLGZpZy53aWR0aD0xNiwgZmlnLmhlaWdodD0xMH0NCiMgQ3JlYXRlIGEgY29sbHVtbiBmb3IgYnJvYWQgaW1wYWN0cw0KaW0gPC0gaW0gJT4lDQogICAgICAgIHNlcGFyYXRlX3Jvd3MoaW1wYWN0LCBzZXAgPSAiLFxccysiKSAlPiUgDQogIG11dGF0ZShpbXBhY3RfYnJvYWQgPSBjYXNlX3doZW4oDQogICAgaW1wYWN0ICVpbiUgYygicGFya2luc29ucyBkaXNlYXNlIiwgImFsemhlaW1lcnMgZGlzZWFzZSIsICJhdXRpc20gc3BlY3RydW0gZGlzb3JkZXIiLCAiYnJhaW4gdHVtb3VyIiwgImFteW90cm9waGljIGxhdGVyYWwgc2NsZXJvc2lzIiApIH4gIk5ldXJvbG9naWNhbCIsDQogICAgaW1wYWN0ICVpbiUgYygiY29uY2VudHJhdGlvbiIsICJjb250YW1pbmF0aW9uIikgfiAiQ29uY2VudHJhdGlvbiIsDQogICAgaW1wYWN0ICVpbiUgYygiZGlhYmV0ZXMiLCAidGh5cm9pZCBmdW5jdGlvbiIsICJoeXBlcnRlbnNpb24iLCAiZW5kb21ldHJpb3NpcyIpIH4gIkVuZG9jcmluZSIsDQogICAgZ3JlcGwoImNhbmNlciIsIGltcGFjdCwgaWdub3JlLmNhc2UgPSBUUlVFKSB8IGltcGFjdCAlaW4lIGMoImxldWtlbWlhIiwgImx5bXBob21hIiwgIm11bHRpcGxlIG15ZWxvbWEiLCAibmV1cm9ibGFzdG9tYSIpIH4gIkNhcmNpbm9nZW4iLA0KICAgIGltcGFjdCAlaW4lIGMoInJlc3BpcmF0b3J5IGhlYWx0aCIsICJjYXJkaW92YXNjdWxhciBkaXNlYXNlIiwgImFzdGhtYSIsICJwcm9sb25nZWQgYnJhZHljYXJkaWEiKSB+ICJDYXJkaW92YXNjdWxhciIsDQogIyAgIGltcGFjdCAlaW4lIGMoImJpcnRoIG91dGNvbWVzIiwgImJpcnRoIHdlaWdodCIsICJwcmV0ZXJtIGJpcnRoIikgfiAiQmlydGgiLA0KICAgIGltcGFjdCAlaW4lIGMoIm9iZXNpdHkiLCAiYWRpcG9zaXR5IikgfiAiT2Jlc2l0eSIsDQogICAgaW1wYWN0ICVpbiUgYygic3Blcm0gcXVhbGl0eSIsICJuZXVyb2JsYXN0b21hIiwgImh5cG9zcGFkaWFzIiwgImNyeXB0b2NoaWRpc20iLCAicmVwcm9kdWN0aXZlIHN5c3RlbSIpIH4gIlJlcHJvZHVjdGlvbiIsDQogICAgVFJVRSB+ICJPdGhlciBJbXBhY3QiDQogICkpDQoNCg0KIyBDYWxjdWxhdGUgdG90YWwgY291bnQgZm9yIGVhY2ggY2F0ZWdvcnkNCmltcGFjdF9jb3VudF9icm9hZCA8LSANCiAgaW0gJT4lIA0KICAgIHNlcGFyYXRlX3Jvd3MoaW1wYWN0X2Jyb2FkLCBzZXAgPSAiLFxccysiKSAlPiUgDQogICAgY291bnQoaW1wYWN0X2Jyb2FkKSAlPiUgDQogIGZpbHRlcihpbXBhY3RfYnJvYWQgIT0gIk5BIikgJT4lDQogICAgZ3JvdXBfYnkoaW1wYWN0X2Jyb2FkKSAlPiUNCiAgc3VtbWFyaXNlKG4gPSBzdW0obikpDQoNCiMgQ2FsY3VsYXRlIHByb3BvcnRpb24gYW5kIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkNCmltcGFjdF9wY3RfYnJvYWQgPC0gaW1wYWN0X2NvdW50X2Jyb2FkICU+JQ0KICBtdXRhdGUocHJvcG9ydGlvbiA9IG4vc3VtKGltcGFjdF9jb3VudF9icm9hZCRuKSwNCiAgICAgICAgIHBlcmNlbnRhZ2UgPSBwcm9wb3J0aW9uKjEwMCkNCg0KDQojIENyZWF0ZSB0aGUgY291bnQgcGxvdCBmb3IgaW1wYWN0cyANCmZpZ3MzMCA8LSBpbXBhY3RfY291bnRfYnJvYWQgJT4lDQogIGdncGxvdChhZXMoeCA9IG4sIHkgPSByZW9yZGVyKGltcGFjdF9icm9hZCwgbiksIGZpbGwgPSAiIzFiOWU3NyIpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDAuOCAsIGFscGhhID0gMC43KSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBuLCB4ID0gbiAvIDIsIHkgPSByZW9yZGVyKGltcGFjdF9icm9hZCwgbikpLCBoanVzdCA9IDAuNSwgc2l6ZSA9IDcsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZW9tX3RleHQoZGF0YSA9IGltcGFjdF9wY3RfYnJvYWQsIGFlcyhsYWJlbCA9IHBhc3RlMCgiKCIsIHJvdW5kKHBlcmNlbnRhZ2UsIDEpLCAiJSkiKSwgeCA9IG4pLCANCiAgICAgICAgICAgIGhqdXN0ID0gLTAuMSwgc2l6ZSA9IDYsIGNvbG9yID0gImJsYWNrIiwgZm9udGZhY2UgPSAiYm9sZCIpICsNCiAgc2NhbGVfZmlsbF9pZGVudGl0eShndWlkZSA9ICJub25lIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZSA9ICJBcnRpY2xlIENvdW50IiwgZXhwYW5kID0gYygwLCAwKSwgbGltaXRzID0gYygwLCBtYXgoaW1wYWN0X2NvdW50X2Jyb2FkJG4pKjEuMSkpICsNCiAgbGFicyh5ID0gTlVMTCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBheGlzLmxpbmUueCA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJncmF5Iiwgc2l6ZSA9IDAuNSksDQogICAgICAgIGF4aXMubGluZS55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yLnkgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IueSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiDQogICAgICAgICkNCg0KZmlnczMwDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczMwLnBkZiIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczMwLmpwZyIpLCB3aWR0aCA9IDE2LCBoZWlnaHQgPSAxMCwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzMzENCkFuIGFsbHV2aWFsIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSBwZXN0aWNpZGUgb2YgZXhwb3N1cmUsIHRoZSBzdWJqZWN0IGJlaW5nIGV4cG9zZWQgYW5kIHRoZSBpbXBhY3Qgb2YgZXhwb3N1cmUgDQpgYGB7cixmaWcud2lkdGg9MTgsIGZpZy5oZWlnaHQ9MTJ9DQoNCiMgRnVuY3Rpb24gdG8gY2hhbmdlIE9DUCB0byBiZSBtb3JlIGdlbmVyYWwNCnJlcGxhY2Vfb2NwMiA8LSBmdW5jdGlvbihkZikgew0KICBkZiAlPiUgDQogIG11dGF0ZShvY3AgPSBjYXNlX3doZW4oDQogICAgZ3JlcGwoIkNobG9yZGFuZSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJDaGxvcmRhbmUiLCAgDQogICAgZ3JlcGwoIkVuZG9zdWxmYW4iLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRW5kb3N1bGZhbiIsIA0KICAgIGdyZXBsKCJOb25hY2hsb3IiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiTm9uYWNobG9yZSIsIA0KICAgIGdyZXBsKCJIZXB0YWNobG9yIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkhlcHRhY2hsb3IiLA0KICAgIGdyZXBsKCJUQ0REIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIlRDREQiLCANCiAgICBncmVwbCgiRW5kcmluIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkVuZHJpbiIsDQogICAgZ3JlcGwoIkhleGFjaGxvcm9iZW56ZW5lIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkhDSCIsDQogICAgZ3JlcGwoIkxpbmRhbmUiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiSENIIiwgDQogICAgZ3JlcGwoIkhleGFjaGxvcm9jeWNsb2hleGFuZSBcXChIQ0hcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiSENIIiwNCiAgICBncmVwbCgiYWxwaGEtSGV4YWNobG9yb2N5Y2xvaGV4YW5lIFxcKGFscGhhLUhDSFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJIQ0giLA0KICAgIGdyZXBsKCJiZXRhLUhleGFjaGxvcm9jeWNsb2hleGFuZSBcXChiZXRhLUhDSFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJIQ0giLA0KICAgIGdyZXBsKCJnYW1tYS1IZXhhY2hsb3JvY3ljbG9oZXhhbmUgXFwoZ2FtbWEtSENIXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkhDSCIsDQogICAgZ3JlcGwoIkRpY2hsb3JvZGlwaGVueWx0cmljaGxvcm9ldGhhbmUgXFwoRERUXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkREVCIsDQogICAgZ3JlcGwoInAscC1EaWNobG9yb2RpcGhlbnlsdHJpY2hsb3JvZXRoYW5lIFxcKHAscC1ERFRcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiRERUIiwNCiAgICBncmVwbCgibyxwLURpY2hsb3JvZGlwaGVueWx0cmljaGxvcm9ldGhhbmUgXFwobyxwLUREVFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJERFQiLA0KICAgIGdyZXBsKCJEaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGhhbmUgXFwoREREXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERCIsDQogICAgZ3JlcGwoInAscC1EaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGhhbmUgXFwocCxwLURERFxcKSIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSB+ICJEREQiLA0KICAgIGdyZXBsKCJvLHAtRGljaGxvcm9kaXBoZW55bGRpY2hsb3JvZXRoYW5lIFxcKG8scC1ERERcXCkiLCBvY3AsIGlnbm9yZS5jYXNlID0gVFJVRSkgfiAiREREIiwNCiAgICBncmVwbCgiRGljaGxvcm9kaXBoZW55bGRpY2hsb3JvZXRoeWxlbmUgXFwoRERFXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERSIsDQogICAgZ3JlcGwoInAscC1EaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGh5bGVuZSBcXChwLHAtRERFXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERSIsDQogICAgZ3JlcGwoIm8scC1EaWNobG9yb2RpcGhlbnlsZGljaGxvcm9ldGh5bGVuZSBcXChvLHAtRERFXFwpIiwgb2NwLCBpZ25vcmUuY2FzZSA9IFRSVUUpIH4gIkRERSIsDQogICAgVFJVRSB+IG9jcA0KICApKQ0KfQ0KIA0KIyBUcmFuc2Zvcm0gdGhlIGRhdGEgDQphbGx1dmlhbCA8LSBpbSAlPiUNCiAgbGVmdF9qb2luKG9jcCwgYnkgPSAic3R1ZHlfaWQiKSAlPiUNCiAgbGVmdF9qb2luKHN1YiwgYnkgPSAic3R1ZHlfaWQiKSAlPiUNCiAgc2VwYXJhdGVfcm93cyhzdWJqZWN0LCBzZXAgPSAiLFxccysiKSAlPiUgDQogIHNlcGFyYXRlX3Jvd3Mob2NwLCBzZXAgPSAiLFxccysiKSAlPiUgDQogIHNlcGFyYXRlX3Jvd3MoaW1wYWN0X2Jyb2FkLCBzZXAgPSAiLFxccysiKSAlPiUNCiAgcmVwbGFjZV9vY3AyKCkgJT4lDQogIGZpbHRlcighZ3JlcGwoIm5vdCByZXBvcnRlZCIsIG9jcCwgaWdub3JlLmNhc2UgPSBUUlVFKSkgJT4lDQogIGdyb3VwX2J5KG9jcCwgc3ViamVjdCwgaW1wYWN0X2Jyb2FkKSAlPiUNCiAgc3VtbWFyaXNlKGZyZXEgPSBuKCksIC5ncm91cHMgPSAnZHJvcCcpICU+JQ0KICBncm91cF9ieShvY3ApICU+JQ0KICBmaWx0ZXIoc3VtKGZyZXEpID4gMTApICU+JSAgDQogIGdyb3VwX2J5KGltcGFjdF9icm9hZCkgJT4lIA0KICBmaWx0ZXIoc3VtKGZyZXEpID4gNSkgJT4lIA0KICBtdXRhdGUoc3ViamVjdCA9IGZhY3RvcihzdWJqZWN0LCBsZXZlbHMgPSBjKCJFbnZpcm9ubWVudCIsICJOb24taHVtYW4gYW5pbWFsIiwgIkh1bWFuIiksIG9yZGVyZWQgPSBUUlVFKSkNCg0KIyBNYWtlIGFsbHV2aWFsIHBsb3QNCmZpZ3MzMSA8LSBhbGx1dmlhbCAlPiUgDQogIGdncGxvdCgNCiAgICAgICBhZXMoYXhpczEgPSBvY3AsIGF4aXMyID0gc3ViamVjdCwgYXhpczMgPSBpbXBhY3RfYnJvYWQsIHkgPSBmcmVxKSkgKw0KICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IGMoIk9yZ2Fub2NobG9yaW5lIFBlc3RpY2lkZSIsICJTdWJqZWN0IiwgIkltcGFjdCIpLCBleHBhbmQgPSBjKC4wNSwgLjEwKSkgKw0KICB4bGFiKCJWYXJpYWJsZXMiKSArDQogIHlsYWIoIkZyZXF1ZW5jeSIpICsgIA0KICBnZW9tX2FsbHV2aXVtKGFlcyhmaWxsID0gc3ViamVjdCkpICsNCiAgZ2VvbV9zdHJhdHVtKHdpZHRoID0gMS8yLCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGdlb21fdGV4dChzdGF0ID0gInN0cmF0dW0iLCBhZXMobGFiZWwgPSBhZnRlcl9zdGF0KHN0cmF0dW0pKSwgc2l6ZSA9IDUsIGZvbnRmYWNlID0gImJvbGQiKSArICANCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgdGhlbWUoYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE1KSwgIA0KICAgICAgICBheGlzLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTIwKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgIA0KICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpICANCiAgKSArIA0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkRhcmsyIiwgbmFtZSA9ICJTdWJqZWN0IENhdGVnb3J5IikNCg0KZmlnczMxDQoNCiMgZ2dzYXZlKGhlcmUoImZpZ3VyZXMiLCAiZmlnczMxLnBkZiIpLCB3aWR0aCA9MTgsIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWdzMzEuanBnIiksIHdpZHRoID0gMTgsIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KDQoNCmBgYA0KDQoNCiMjIEZpZ3VyZSA0DQpBIGJ1YmJsZSBwbG90IHNob3dpbmcgdGhlIGNvdW50cyBvZiBlYWNoIHBlc3RpY2lkZSBwZXIgaW1wYWN0IGluY2x1ZGVkIGluIGN1cnJlbnQgbWV0YS1hbmFseXNpcyBvbiB0aGUgaW1wYWN0cyBvZiBvcmhhbm9jaGxvcmluZSBwZXN0aWNpZGVzIA0KYGBge3IsZmlnLndpZHRoPTI1LCBmaWcuaGVpZ2h0PTE1fQ0KDQojIEpvaW4gdGhlIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZSBkZXRhaWxzIHdpdGggdGhlIGltcGFjdCBkZXRhaWxzDQpvY3BfaW0gPC0gbGVmdF9qb2luKG9jcCwgaW0gLHN1YiwgYnkgPSAic3R1ZHlfaWQiKSANCg0KIyBTZXBhcmF0ZSByb3dzIGluICJvY3BfaW0iDQpvY3BfaW0xIDwtIHNlcGFyYXRlX3Jvd3Mob2NwX2ltLCBvY3AgLCBzZXAgPSAiLCAiLCBjb252ZXJ0ID0gVFJVRSkNCg0KDQojIEdyb3VwIGJ5ICJvY3AiIGFuZCAiaW1wYWN0IiBhbmQgc3VtbWFyaXplIGNvdW50DQpvY3BfaW1fc3VtbWFyeSA8LSBvY3BfaW0xICU+JQ0KICBtdXRhdGUob2NwID0gc3RyX3RyaW0ob2NwKSwNCiAgICAgICAgIGltcGFjdF9icm9hZCA9IHN0cl90cmltKGltcGFjdF9icm9hZCkpICU+JQ0KICAgIHJlcGxhY2Vfb2NwMigpICU+JSANCiAgZ3JvdXBfYnkob2NwLCBpbXBhY3RfYnJvYWQpICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksIC5ncm91cHMgPSAiZHJvcCIpIA0KDQoNCiMgRmlsdGVyIGZvciB0b3AgNSBwZXN0aWNpZGVzIA0KdG9wX3Blc3RpY2lkZXMgPC0gb2NwX2ltX3N1bW1hcnkgJT4lDQogIGZpbHRlcihvY3AgIT0gIm5vdCByZXBvcnRlZCIpICU+JQ0KICBncm91cF9ieShvY3ApICU+JQ0KICBzdW1tYXJpc2UodG90YWxfY291bnQgPSBzdW0oY291bnQpKSAlPiUNCiAgdG9wX24oOCwgdG90YWxfY291bnQpICU+JQ0KICBwdWxsKG9jcCkgDQoNCg0Kb2NwX2ltX3N1bW1hcnlfZmlsdGVyZWQgPC0gb2NwX2ltX3N1bW1hcnkgJT4lDQogIGZpbHRlcihvY3AgJWluJSB0b3BfcGVzdGljaWRlcykNCg0KIyBDcmVhdGUgYSBjaXJjbGUgcGxvdCB3aXRoIGltcGFjdCBvbiB0aGUgeC1heGlzIGFuZCBvY3Agb24gdGhlIHktYXhpcw0KZmlnNCA8LSBvY3BfaW1fc3VtbWFyeV9maWx0ZXJlZCAlPiUgDQpnZ3Bsb3QoYWVzKHggPSBmY3RfcmV2KGZjdF9yZW9yZGVyKGltcGFjdF9icm9hZCwgY291bnQsIC5mdW4gPSAnc3VtJykpLA0KICAgICAgICAgICB5ID0gZmN0X3Jlb3JkZXIob2NwLCBjb3VudCwgLmZ1biA9ICdzdW0nKSwNCiAgICAgICAgICAgc2l6ZSA9IGNvdW50LA0KICAgICAgICAgICBmaWxsID0gY291bnQpKSArDQogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgY29sb3IgPSAid2hpdGUiKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBjb3VudCksIHNpemUgPSA4LCBmb250ZmFjZSA9ICJib2xkIikgKyAgDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiM5OEZCOTgiLCBoaWdoID0gIiMwMDY0MDAiKSArDQogIGxhYnMoeCA9ICJJbXBhY3QiLA0KICAgICAgIHkgPSAiT3JnYW5vY2hsb3JpbmUgUGVzdGljaWRlIiwNCiAgICAgICBmaWxsID0gIkNvdW50IikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICAgICAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLCAgDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCwgaGp1c3QgPSAxKSwgIA0KICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgIA0KICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwgIA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygxNSwgNDUpKSANCg0KZmlnNA0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzQucGRmIiksIHdpZHRoID0gMjUsIGhlaWdodCA9IDE1LCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc0LmpwZyIpLCB3aWR0aCA9IDI1LCBoZWlnaHQgPSAxNSwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCiAgDQpgYGANCg0KIyBPYmplY3RpdmUgMw0KVG8gaW52ZXN0aWdhdGUgZ2xvYmFsIHJlc2VhcmNoIG91dHB1dCBhbmQgY29sbGFib3JhdGlvbiBuZXR3b3Jrcw0KDQojIyBGaWd1cmUgczMyLCBzMzMsIHMzNCwgczM1ICYgczM2DQpgYGB7cixmaWcud2lkdGg9MTYsIGZpZy5oZWlnaHQ9MTB9DQpmaWdzMzIgPC0gYmlibGlvQW5hbHlzaXMoYmliX3NjbykNCnBsb3QoZmlnczMyKQ0Kc3VtbWFyeShmaWdzMzIpDQoNCmBgYA0KDQojIyBGaWd1cmUgczM3DQpUaGVtYXRpYyBtYXAgYmFzZWQgb24ga2V5d29yZHMgZXh0cmFjdGVkIGZyb20gSUQgZmllbGQgKG9idGFpbmVkIG9uIHRoZSBTY29wdXMgc2NpZW50aWZpYyBsaXRlcmF0dXJlIGRhdGFiYXNlKSBvZiBtZXRhLWFuYWx5c2lzIGluY2x1ZGVkIGluIHRoZSBzeXN0ZW1hdGljIHJldmlldyBtYXAuIA0KYGBge3IsZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTEwfQ0KcGFyKG1mcm93PWMoMSwxKSwgbWFyPWMoMCwyLDAsMikpDQpmaWczNyA8LSB0aGVtYXRpY01hcChiaWJfc2NvLCBmaWVsZCA9ICJJRCIsIG4gPSAxNTAwLCBtaW5mcmVxID0gMSwgc3RlbW1pbmcgPSBGQUxTRSwgc2l6ZSA9IDEsIG4ubGFiZWxzID0gMSwgcmVwZWwgPSBUUlVFKQ0KcGxvdChmaWczNyRtYXApDQoNCmBgYA0KDQojIyBGaWd1cmUgNSANCkhlYXQgbWFwIG9mIHdvcmxkIHNob3dpbmcgdGhlIGNvdW50cnktbGV2ZWwgY291bnRzIGZvciBmaXJzdCBhdXRob3Jz4oCZIGNvdW50cnkgb2YgYWZmaWxpYXRpb24gb2YgbWV0YS1hbmFseXNpcyBpbnZlc3RpZ2F0aW5nIHRoZSBpbXBhY3RzIG9mIG9yZ2Fub2NobG9yaW5lIHBlc3RpY2lkZXMuIEdyZXkgaW5kaWNhdGVzIG5vIHB1YmxpY2F0aW9ucyBhZmZpbGlhdGVkIHdpdGggYSBnaXZlbiBjb3VudHJ5IGluIG91ciBkYXRhIHNldC4gDQpgYGB7cixmaWcud2lkdGg9IDIxLCBmaWcuaGVpZ2h0PTEyfQ0KIyBFeHRyYWN0IGNvdW50cnkgaW5mb3JtYXRpb24gZnJvbSB0aGUgIkFVMV9DTyIgYW5kICJBVV9DTyIgZmllbGRzIG9mIHRoZSAiYmliX3NjbyIgZGF0YXNldA0KYmlibWFwIDwtIG1ldGFUYWdFeHRyYWN0aW9uKGJpYl9zY28sIEZpZWxkID0gIkFVMV9DTyIsIHNlcCA9ICI7IikgDQpiaWJtYXAgPC0gbWV0YVRhZ0V4dHJhY3Rpb24oYmlibWFwLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikgDQoNCiMgQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIGNvdW50cyBvZiBhcnRpY2xlcyBmcm9tIGVhY2ggY291bnRyeQ0KZmlyc3Rjb3VudHJ5Y291bnRzIDwtIGJpYm1hcCAlPiUgDQogIGdyb3VwX2J5KEFVMV9DTykgJT4lIA0KICBjb3VudCgpICU+JSANCiAgZmlsdGVyKCFpcy5uYShBVTFfQ08pKSAgDQoNCiMgTG9hZCB3b3JsZCBtYXAgZGF0YSBhbmQgcmVtb3ZlIGNvdW50cmllcyB3aXRoIGxvbmdpdHVkZSA+MTgwIHRvIG1ha2UgYW4gZXF1YWwgcHJvamVjdGlvbi1saWtlIG1hcA0Kd29ybGRfbWFwIDwtIG1hcF9kYXRhKCJ3b3JsZCIpICU+JSANCiAgZmlsdGVyKCEgbG9uZyA+IDE4MCkNCg0KIyBGb3JtYXQgY291bnRyeSBuYW1lcyB0byBtYXRjaCByZWdpb25zIG9uIHRoZSB3b3JsZCBtYXANCmZpcnN0Y291bnRyeWNvdW50cyRyZWdpb24gPC0gc3RyX3RvX3RpdGxlKGZpcnN0Y291bnRyeWNvdW50cyRBVTFfQ08pDQpmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uW2ZpcnN0Y291bnRyeWNvdW50cyRyZWdpb24gPT0gIlVzYSJdIDwtICJVU0EiIA0KZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbltmaXJzdGNvdW50cnljb3VudHMkcmVnaW9uID09ICJLb3JlYSJdIDwtICJTb3V0aCBLb3JlYSINCmZpcnN0Y291bnRyeWNvdW50cyRyZWdpb25bZmlyc3Rjb3VudHJ5Y291bnRzJHJlZ2lvbiA9PSAiVW5pdGVkIEtpbmdkb20iXSA8LSAiVUsiDQoNCiMgSm9pbiBjb3VudCBkYXRhIHdpdGggbWFwIGRhdGEgYW5kIHNldCBtaXNzaW5nIGNvdW50cyB0byB6ZXJvDQplbXB0eW1hcCA8LSB0aWJibGUocmVnaW9uID0gdW5pcXVlKHdvcmxkX21hcCRyZWdpb24pLCBuID0gcmVwKDAsbGVuZ3RoKHVuaXF1ZSh3b3JsZF9tYXAkcmVnaW9uKSkpKQ0KZnVsbG1hcCA8LSBsZWZ0X2pvaW4oZW1wdHltYXAsIGZpcnN0Y291bnRyeWNvdW50cywgYnkgPSAicmVnaW9uIikNCmZ1bGxtYXAkbiA8LSBmdWxsbWFwJG4ueCArIGZ1bGxtYXAkbi55DQpmdWxsbWFwJG5baXMubmEoZnVsbG1hcCRuKV0gPC0gMA0KDQpmaWc1IDwtIGZ1bGxtYXAgJT4lDQogIGdncGxvdChhZXMoZmlsbCA9IG4sIG1hcF9pZCA9IHJlZ2lvbikpICsNCiAgZ2VvbV9tYXAobWFwID0gd29ybGRfbWFwLCBjb2xvciA9ICJncmF5NTAiKSArDQogIGV4cGFuZF9saW1pdHMoeCA9IHdvcmxkX21hcCRsb25nLCB5ID0gd29ybGRfbWFwJGxhdCkgKw0KICBjb29yZF9tYXAoIm1lcmNhdG9yIikgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksICANCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgDQogICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsDQogICAgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIiwgIA0KICAgIGxlZ2VuZC5ib3guanVzdCA9ICJjZW50ZXIiLCAgDQogICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbih0ID0gMTAsIHVuaXQgPSAicHQiKSwgIA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksICANCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwgIA0KICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDMwLCAibW0iKSAgDQogICkgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KA0KICAgIGxvdyA9ICIjOThGQjk4IiwgaGlnaCA9ICIjMDA2NDAwIiwNCiAgICBuYW1lID0gIlNjb3JlIiwgbmEudmFsdWUgPSAiZ3JheTcwIiwNCiAgICBsaW1pdHMgPSBjKDEsIDIwKSkgKw0KICBndWlkZXMoDQogICAgZmlsbCA9IGd1aWRlX2NvbG91cmJhcigNCiAgICAgIGJhcndpZHRoID0gdW5pdCgxODAsIHVuaXRzID0gIm1tIiksDQogICAgICBiYXJoZWlnaHQgPSB1bml0KDMsIHVuaXRzID0gIm1tIikNCiAgICApDQogICkNCg0KZmlnNQ0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZzUucGRmIiksIHdpZHRoID0gMjEsIGhlaWdodCA9IDEyLCB1bml0cyA9ICJjbSIsIHNjYWxlID0gMiwgZHBpID0gODAwKQ0KIyBnZ3NhdmUoaGVyZSgiZmlndXJlcyIsICJmaWc1LmpwZyIpLCB3aWR0aCA9IDIxLCBoZWlnaHQgPSAxMiwgdW5pdHMgPSAiY20iLCBzY2FsZSA9IDIsIGRwaSA9IDgwMCkNCg0KYGBgDQoNCiMjIEZpZ3VyZSBzNDMNCkhlYXQgbWFwIG9mIEV1cm9wZSBzaG93aW5nIHRoZSBjb3VudHJ5LWxldmVsIGNvdW50cyBmb3IgZmlyc3QgYXV0aG9yc+KAmSBjb3VudHJ5IG9mIGFmZmlsaWF0aW9uIG9mIG1ldGEtYW5hbHlzaXMgaW52ZXN0aWdhdGluZyB0aGUgaW1wYWN0cyBvZiBvcmdhbm9jaGxvcmluZSBwZXN0aWNpZGVzLiBHcmV5IGluZGljYXRlcyBubyBwdWJsaWNhdGlvbnMgYWZmaWxpYXRlZCB3aXRoIGEgZ2l2ZW4gY291bnRyeSBpbiBvdXIgZGF0YSBzZXQuIA0KYGBge3IsZmlnLndpZHRoPSAyMSwgZmlnLmhlaWdodD0xMn0NCmZpZ3M0MyA8LSBmdWxsbWFwICU+JQ0KZ2dwbG90KGFlcyhmaWxsID0gbiwgbWFwX2lkID0gcmVnaW9uKSkgKw0KZ2VvbV9tYXAobWFwID0gd29ybGRfbWFwLCBjb2xvciA9ICJncmF5NTAiKSArDQpjb29yZF9tYXAoIm1lcmNhdG9yIiwgeWxpbSA9IGMoMzAsIDY1KSwgeGxpbSA9IGMoLTM1LCA1NSkpICsgDQp0aGVtZSgNCiAgICBheGlzLnRleHQgPSBlbGVtZW50X2JsYW5rKCksICANCiAgICBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCAgDQogICAgbGVnZW5kLmJveCA9ICJob3Jpem9udGFsIiwgIA0KICAgIGxlZ2VuZC5ib3guanVzdCA9ICJjZW50ZXIiLCAgDQogICAgbGVnZW5kLm1hcmdpbiA9IG1hcmdpbih0ID0gMTAsIHVuaXQgPSAicHQiKSwgIA0KICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksICANCiAgICBsZWdlbmQudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE0LCBmYWNlID0gImJvbGQiKSwgIA0KICAgIGxlZ2VuZC5rZXkud2lkdGggPSB1bml0KDMwLCAibW0iKSwNCiAgICBsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiAgDQogICkgKw0Kc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiIzk4RkI5OCIsIGhpZ2ggPSAiIzAwNjQwMCIsDQogICAgbmFtZSA9ICJTY29yZSIsIG5hLnZhbHVlID0gImdyYXk3MCIsDQogICAgbGltaXRzID0gYygxLCAxMCkpICsNCmd1aWRlcyhmaWxsID0gZ3VpZGVfY29sb3VyYmFyKGJhcndpZHRoID0gdW5pdCgxODAsIHVuaXRzID0gIm1tIiksIGJhcmhlaWdodCA9IHVuaXQoMywgdW5pdHMgPSAibW0iKSkpDQoNCmZpZ3M0Mw0KDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M0My5wZGYiKSwgd2lkdGggPSAyMSwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQojIGdnc2F2ZShoZXJlKCJmaWd1cmVzIiwgImZpZ3M0My5qcGciKSwgd2lkdGggPSAyMSwgaGVpZ2h0ID0gMTIsIHVuaXRzID0gImNtIiwgc2NhbGUgPSAyLCBkcGkgPSA4MDApDQpgYGANCg0KIyMgRmlndXJlIHM0NA0KQ2hvcmQgZGlhZ3JhbSBvZiBjb2xsYWJvcmF0aW9ucyBhY3Jvc3MgY291bnRyaWVzLiBDb3VudHJpZXMgcmVwcmVzZW50IHRoZSBsb2NhdGlvbiBvZiB0aGUgcHJpbWFyeSBhdXRob3Jz4oCZIGFmZmlsaWF0ZWQgaW5zdGl0dXRpb24uIA0KYGBge3IsZmlnLndpZHRoPSAxMiwgZmlnLmhlaWdodD0xMn0NCiMgRXh0cmFjdCBjb3VudHJpZXMgZnJvbSB0aGUgYWZmaWxpYXRpb25zDQpiaWJfc2NvMiA8LSBtZXRhVGFnRXh0cmFjdGlvbihiaWJfc2NvLCBGaWVsZCA9ICJBVV9DTyIsIHNlcCA9ICI7IikNCg0KIyBDcmVhdGUgYSBuZXR3b3JrIG1hdHJpeCBvZiBjb2xsYWJvcmF0aW9ucyBiZXR3ZWVuIGNvdW50cmllcw0KTmV0TWF0cml4X2NvdW50cnkgPC0gYmlibGlvTmV0d29yayhiaWJfc2NvMiwgYW5hbHlzaXMgPSAiY29sbGFib3JhdGlvbiIsIG5ldHdvcmsgPSAiY291bnRyaWVzIiwgc2VwID0gIjsiKQ0KDQojIENvbnZlcnQgdGhlIG5ldHdvcmsgbWF0cml4IHRvIGEgc3RhbmRhcmQgbWF0cml4DQpOZXRNYXRyaXhfY291bnRyeSA8LSBhcy5tYXRyaXgoTmV0TWF0cml4X2NvdW50cnkpDQoNCiMgUmVtb3ZlIHRoZSBsb3dlciB0cmlhbmdsZSAoYXMgdGhpcyBpcyBkdXBsaWNhdGlvbiBvZiBpbmZvKQ0KTmV0TWF0cml4X2NvdW50cnlbbG93ZXIudHJpKE5ldE1hdHJpeF9jb3VudHJ5KV0gPC0gMCANCg0KIyBDaGFuZ2UgY29sdW1uIGFuZCByb3cgbmFtZXMgdG8gdGl0bGUgY2FzZQ0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpIDwtIHN0cl90b190aXRsZShjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkpDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPC0gc3RyX3RvX3RpdGxlKHJvd25hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSkNCg0KIyBDaGFuZ2UgIlVzYSIgdG8gIlVTQSINCmNvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KVtjb2xuYW1lcyhOZXRNYXRyaXhfY291bnRyeSkgPT0gIlVzYSJdIDwtICJVU0EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSlbcm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpID09ICJVc2EiXSA8LSAiVVNBIg0KDQojIENoYW5nZSAiVW5pdGVkIEtpbmdkb20iIHRvICJVSyIgZm9yIGVhc2llciBwbG90dGluZw0KY29sbmFtZXMoTmV0TWF0cml4X2NvdW50cnkpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb3VudHJ5KSA9PSAiVW5pdGVkIEtpbmdkb20iXSA8LSAiVUsiDQpyb3duYW1lcyhOZXRNYXRyaXhfY291bnRyeSlbcm93bmFtZXMoTmV0TWF0cml4X2NvdW50cnkpID09ICJVbml0ZWQgS2luZ2RvbSJdIDwtICJVSyINCg0KIyBTZXR0aW5nIHVwIGN1c3RvbSBwYXJhbWV0ZXJzDQpjaXJjb3MucGFyKGNlbGwucGFkZGluZyA9IGMoMCwgMCwgMCwgMCksIHRyYWNrLm1hcmdpbiA9IGMoMCwgMCkpDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3M0NCA8LSBjaG9yZERpYWdyYW0oTmV0TWF0cml4X2NvdW50cnksIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBiZy5ib3JkZXIgPSBOQSwgcGFuZWwuZnVuID0gZnVuY3Rpb24oeCwgeSkgew0KICB4bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ4bGltIikNCiAgeWxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieWxpbSIpDQogIHNlY3Rvci5uYW1lID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJzZWN0b3IuaW5kZXgiKQ0KICBjaXJjb3MudGV4dChtZWFuKHhsaW0pLCB5bGltWzFdICsgMC4yICwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwKSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0pDQoNCmBgYA0KDQojIyBGaWd1cmUgczQ1DQpDaG9yZCBkaWFncmFtIGlsbHVzdHJhdGlvbiBvZiBjb2xsYWJvcmF0aW9ucyBhY3Jvc3MgY291bnRyaWVzLiBDb3VudHJpZXMgcmVwcmVzZW50IHRoZSBsb2NhdGlvbiBvZiB0aGUgcHJpbWFyeSBhdXRob3Jz4oCZIGFmZmlsaWF0ZWQgaW5zdGl0dXRpb24uIENvbGxhYm9yYXRpb25zIHdpdGhpbiBjb3VudHJpZXMgYXJlIG5vdCBzaG93bi4NCmBgYHtyLGZpZy53aWR0aD0gMTIsIGZpZy5oZWlnaHQ9MTJ9DQpkaWFnKE5ldE1hdHJpeF9jb3VudHJ5KSA8LSAwDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3M0NSA8LSBjaG9yZERpYWdyYW0oTmV0TWF0cml4X2NvdW50cnksIGFubm90YXRpb25UcmFjayA9ICJncmlkIiwgcHJlQWxsb2NhdGVUcmFja3MgPSAxKQ0KDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAwLjIsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMC41KSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0sIGJnLmJvcmRlciA9IE5BKQ0KYGBgDQoNCiMjIEZpZ3VyZSBzNDYNCkNob3JkIGRpYWdyYW0gaWxsdXN0cmF0aW9uIG9mIGNvbGxhYm9yYXRpb25zIGFjcm9zcyBjb250aW5lbnRzLiBDb250aW5lbnRzIHJlcHJlc2VudCB0aGUgbG9jYXRpb24gb2YgdGhlIHByaW1hcnkgYXV0aG9yc+KAmSBhZmZpbGlhdGVkIGluc3RpdHV0aW9uLiBDb2xsYWJvcmF0aW9ucyB3aXRoaW4gY291bnRyaWVzIGFyZSBub3Qgc2hvd24uDQpgYGB7cixmaWcud2lkdGg9IDEyLCBmaWcuaGVpZ2h0PTEyfQ0KIyBDb3VudHJ5IHJlbmFtZSB0byBjb250aW5lbnRzDQpOZXRNYXRyaXhfY29udGluZW50IDwtIE5ldE1hdHJpeF9jb3VudHJ5DQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVVNBIl0gPC0gIk5vcnRoXG5BbWVyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlVTQSJdIDwtICJOb3J0aFxuQW1lcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlNwYWluIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTcGFpbiJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDaGluYSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNoaW5hIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJGcmFuY2UiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZyYW5jZSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDYW5hZGEiXSA8LSAiTm9ydGhcbkFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ2FuYWRhIl0gPC0gIk5vcnRoXG5BbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRGVubWFyayJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRGVubWFyayJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOZXRoZXJsYW5kcyJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTmV0aGVybGFuZHMiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQmVsZ2l1bSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQmVsZ2l1bSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJVSyJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVUsiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQXVzdHJhbGlhIl0gPC0gIkF1c3RyYWxpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiQXVzdHJhbGlhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoIEFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQnJhemlsIl0gPC0gIlNvdXRoIEFtZXJpY2EiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHZXJtYW55Il0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHZXJtYW55Il0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZpbmxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkZpbmxhbmQiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiR3JlZWNlIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJHcmVlY2UiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiS29yZWEiXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLb3JlYSJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTm9yd2F5Il0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJOb3J3YXkiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dlZGVuIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTd2VkZW4iXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiRWd5cHQiXSA8LSAiQWZyaWNhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkVneXB0Il0gPC0gIkFmcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkl0YWx5Il0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJdGFseSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJKYXBhbiJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkphcGFuIl0gPC0gIkFzaWEiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJQb3J0dWdhbCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUG9ydHVnYWwiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU3dpdHplcmxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlN3aXR6ZXJsYW5kIl0gPC0gIkV1cm9wZSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlR1cmtleSJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIlR1cmtleSJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSW5kaWEiXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJJbmRpYSJdIDwtICJBc2lhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJhbiJdIDwtICJBc2lhIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIklyYW4iXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkNvc3RhIFJpY2EiXSA8LSAiTm9ydGhcbkFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiQ29zdGEgUmljYSJdIDwtICJOb3J0aFxuQW1lcmljYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkN6ZWNoIFJlcHVibGljIl0gPC0gIkV1cm9wZSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJDemVjaCBSZXB1YmxpYyJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJIb25nIEtvbmciXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJIb25nIEtvbmciXSA8LSAiQXNpYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkljZWxhbmQiXSA8LSAiRXVyb3BlIg0Kcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbcm93bmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkljZWxhbmQiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJlbGFuZCJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiSXJlbGFuZCJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJNZXhpY28iXSA8LSAiTm9ydGhcbkFtZXJpY2EiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiTWV4aWNvIl0gPC0gIk5vcnRoXG5BbWVyaWNhIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUm9tYW5pYSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiUm9tYW5pYSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJTbG92YWtpYSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiU2xvdmFraWEiXSA8LSAiRXVyb3BlIg0KDQpjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVWtyYWluZSJdIDwtICJFdXJvcGUiDQpyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KVtyb3duYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSA9PSAiVWtyYWluZSJdIDwtICJFdXJvcGUiDQoNCmNvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW2NvbG5hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiT2NlYW5pYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJBdXN0cmFsaWEiXSA8LSAiT2NlYW5pYSINCg0KY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudClbY29sbmFtZXMoTmV0TWF0cml4X2NvbnRpbmVudCkgPT0gIkthemFraHN0YW4iXSA8LSAiQXNpYSINCnJvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpW3Jvd25hbWVzKE5ldE1hdHJpeF9jb250aW5lbnQpID09ICJLYXpha2hzdGFuIl0gPC0gIkFzaWEiDQoNCg0KIyBjb2xsYXBzaW5nDQptZXJnZV9tYXRyaXggPC0gdChyb3dzdW0odChOZXRNYXRyaXhfY29udGluZW50KSwgZ3JvdXAgPSBjb2xuYW1lcyhOZXRNYXRyaXhfY29udGluZW50KSwgbmEucm0gPSBUKSkNCm1lcmdlX21hdHJpeDIgPC0gcm93c3VtKG1lcmdlX21hdHJpeCwgZ3JvdXAgPSByb3duYW1lcyhtZXJnZV9tYXRyaXgpKQ0KDQoNCiMgcmVtb3ZlIGRpYWdvbmFsIGVsZW1lbnRzDQpkaWFnKG1lcmdlX21hdHJpeDIpIDwtIDANCg0KIyBjaG9yZCBwbG90DQpjaG9yZERpYWdyYW1Gcm9tTWF0cml4KG1lcmdlX21hdHJpeDIpDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3M0NjwtIGNob3JkRGlhZ3JhbShtZXJnZV9tYXRyaXgyLCBhbm5vdGF0aW9uVHJhY2sgPSAiZ3JpZCIsIHByZUFsbG9jYXRlVHJhY2tzID0gMSkNCiMgQWRkIGEgdHJhY2sgdG8gbGFiZWwgZWFjaCBzZWN0b3Igd2l0aCBpdHMgbmFtZQ0KY2lyY29zLnRyYWNrUGxvdFJlZ2lvbih0cmFjay5pbmRleCA9IDEsIHBhbmVsLmZ1biA9IGZ1bmN0aW9uKHgsIHkpIHsNCiAgeGxpbSA9IGdldC5jZWxsLm1ldGEuZGF0YSgieGxpbSIpDQogIHlsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInlsaW0iKQ0KICBzZWN0b3IubmFtZSA9IGdldC5jZWxsLm1ldGEuZGF0YSgic2VjdG9yLmluZGV4IikNCiAgY2lyY29zLnRleHQobWVhbih4bGltKSwgeWxpbVsxXSArIDAuMiwgc2VjdG9yLm5hbWUsIGZhY2luZyA9ICJjbG9ja3dpc2UiLCBuaWNlRmFjaW5nID0gVFJVRSwgYWRqID0gYygwLCAwLjUpKQ0KICBjaXJjb3MuYXhpcyhoID0gInRvcCIsIGxhYmVscy5jZXggPSAwLjUsIG1ham9yLnRpY2subGVuZ3RoID0gMC4yLCBzZWN0b3IuaW5kZXggPSBzZWN0b3IubmFtZSwgdHJhY2suaW5kZXggPSAyKQ0KfSwgYmcuYm9yZGVyID0gTkEpDQoNCmBgYA0KDQojIyBGaWd1cmUgczQ3DQpDaG9yZCBkaWFncmFtIGlsbHVzdHJhdGlvbiBvZiBjb2xsYWJvcmF0aW9ucyBhY3Jvc3MgZGlzY2lwbGluZXMuIERpc2NpcGxpbmVzIGhhdmUgYmVlbiBhbGxvY2F0ZWQgYmFzZWQgb24gdGhlIEpvdXJuYWwgQ2l0YXRpb24gQ2F0ZWdvcmllcyBvbiBXZWIgb2YgU2NpZW5jZS4gQ29sbGFib3JhdGlvbnMgd2l0aGluIGRpc2NpcGxpbmVzIGFyZSBub3Qgc2hvd24uDQpgYGB7cixmaWcud2lkdGg9IDEyLCBmaWcuaGVpZ2h0PTEyfQ0KZmllbGRzIDwtIHNkICU+JQ0KICBtdXRhdGUoDQogICAgdGl0bGUgPSBzdHJfdG9fbG93ZXIocGFwZXJfdGl0bGUpLA0KICAgIG50aXRsZSA9IHBhc3RlKHN0cl90b19sb3dlcihzdHJfc3BsaXRfZml4ZWQoc3R1ZHlfaWQsICJcXF8iLCBuID0gMilbLDFdKSwgcGFwZXJfdGl0bGUsIHNlcCA9ICIgIiksDQogICAgbnRpdGxlID0gc3RyX3NxdWlzaChudGl0bGUpLA0KICAgIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkID0gc3RyX3JlcGxhY2VfYWxsKEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkLCAiRW52aXJvbm1lbnRhbCBTY2llbmNlIiwgIkVudmlyb25tZW50YWxcblNjaWVuY2UgIikNCiAgKSAlPiUgDQogIHNlbGVjdChudGl0bGUsIEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkKQ0KDQpiaWJfbmFtZXMgPC0gYmliX3NjbyAlPiUgcm93bmFtZXNfdG9fY29sdW1uKC4sIHZhciA9ICJtYXRfbmFtZXMiKSAlPiUgDQogIG11dGF0ZShUSTIgPSB0b2xvd2VyKHVubGlzdChsYXBwbHkoZGF0YS5mcmFtZSh0KHN0cl9zcGxpdF9maXhlZChUSSwgIiAiLCBuID0gMTUpWywxOjE0XSkpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbih4KSBzdHJfYyh4LCBjb2xsYXBzZSAgPSAiICIpKSkpLA0KICAgICAgICAgbmFtZTIgPSBzdHJpX3RyYW5zX2dlbmVyYWwodG9sb3dlcihzdHJfc3BsaXRfZml4ZWQoU1IsICIgIiwgbiA9IDIpWywxXSksICJsYXRpbi1hc2NpaSIpLA0KICAgICAgICAgVEkyID0gcGFzdGUobmFtZTIsIFRJMiwgc2VwPSAiICIpLA0KICAgICAgICAgVEkyID0gdHJpbXdzKFRJMikpICU+JSANCiAgc2VsZWN0KFRJMiwgbWF0X25hbWVzKQ0KDQpwb3MgPC0gbGFwcGx5KGJpYl9uYW1lcyRUSTIsIGZ1bmN0aW9uKHgpIHN0cmluZ2Rpc3QoZmllbGRzJG50aXRsZSwgeCkpDQpwb3MyPC0gbWFwX2RibChwb3MsIHdoaWNoLm1pbikNCg0KDQoNCiMgbm93IHdlIGNhbiBtZXJnZSB0d28gZGF0YXNldHMgDQpiaWJfbmFtZXMkSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQgPC0gZmllbGRzJEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkW3BvczJdDQoNCiMgQ3JlYXRpbmcgbWF0cml4IGZvciBiaWJsaW9tZXRyaWMgY291cGxpbmcNCk5ldE1hdHJpeCA8LSBiaWJsaW9OZXR3b3JrKGJpYl9zY28sIGFuYWx5c2lzID0gImNvdXBsaW5nIiwgbmV0d29yayA9ICJyZWZlcmVuY2VzIiwgc2VwID0gIjsiKQ0KDQojIGZvcmNpbmcgaW50byBhIG5yb21hbCBtYXRyaXgNCm5ldF9tYXRyaXggPC0gYXMubWF0cml4KE5ldE1hdHJpeCkNCg0KZGlhZyhuZXRfbWF0cml4KSA8LSAwICNnZXQgcmlkIG9mIGNvdW50cyBmb3IgdGhlIHNhbWUgcGFwZXJzDQoNCiMgcmVwbGFjaW5nIG5hbWVzIHdpdGggSm91cm5hbF9DYXRlZ29yeV9BbGxvY2F0ZWRfQnJvYWQNCnJvd25hbWVzKG5ldF9tYXRyaXgpIDwtIGJpYl9uYW1lcyRKb3VybmFsX0NhdGVnb3J5X0FsbG9jYXRlZF9Ccm9hZA0KY29sbmFtZXMobmV0X21hdHJpeCkgPC0gYmliX25hbWVzJEpvdXJuYWxfQ2F0ZWdvcnlfQWxsb2NhdGVkX0Jyb2FkDQoNCiMgcmVkdWNpbmcgbWF0cml4IGFjY29yZGluZyB0byBkaXNjaXBsaW5lX2NvZGUNCnJlY3RfbWF0cml4PC0gdChyb3dzdW0odChuZXRfbWF0cml4KSwgZ3JvdXAgPSBjb2xuYW1lcyhuZXRfbWF0cml4KSwgbmEucm0gPSBUKSkNCnNtYWxsX21hdHJpeCA8LSByb3dzdW0ocmVjdF9tYXRyaXgsIGdyb3VwID0gcm93bmFtZXMocmVjdF9tYXRyaXgpKQ0KDQojIGdldHRpbmcgcmlkIG9mIGxvd2VyIHRyaWFuZ2xlIChhcyB0aGlzIGlzIGR1cGxpY2F0aW9uIG9mIGluZm8pDQpzbWFsbF9tYXRyaXhbbG93ZXIudHJpKHNtYWxsX21hdHJpeCldIDwtIDAgDQpwYXIobWFyID0gYygwLCAwLCAwLCAwKSwgbWZyb3cgPSBjKDEsIDEpKQ0KDQoNCiMgQ3JlYXRlIGEgY2hvcmQgZGlhZ3JhbSBvZiB0aGUgbmV0d29yayBtYXRyaXgNCmZpZ3M0NyAgPC0gY2hvcmREaWFncmFtKHNtYWxsX21hdHJpeCwgYW5ub3RhdGlvblRyYWNrID0gImdyaWQiLCBwcmVBbGxvY2F0ZVRyYWNrcyA9IDEpDQojIEFkZCBhIHRyYWNrIHRvIGxhYmVsIGVhY2ggc2VjdG9yIHdpdGggaXRzIG5hbWUNCmNpcmNvcy50cmFja1Bsb3RSZWdpb24odHJhY2suaW5kZXggPSAxLCBwYW5lbC5mdW4gPSBmdW5jdGlvbih4LCB5KSB7DQogIHhsaW0gPSBnZXQuY2VsbC5tZXRhLmRhdGEoInhsaW0iKQ0KICB5bGltID0gZ2V0LmNlbGwubWV0YS5kYXRhKCJ5bGltIikNCiAgc2VjdG9yLm5hbWUgPSBnZXQuY2VsbC5tZXRhLmRhdGEoInNlY3Rvci5pbmRleCIpDQogIGNpcmNvcy50ZXh0KG1lYW4oeGxpbSksIHlsaW1bMV0gKyAwLjIsIHNlY3Rvci5uYW1lLCBmYWNpbmcgPSAiY2xvY2t3aXNlIiwgbmljZUZhY2luZyA9IFRSVUUsIGFkaiA9IGMoMCwgMC41KSkNCiAgY2lyY29zLmF4aXMoaCA9ICJ0b3AiLCBsYWJlbHMuY2V4ID0gMC41LCBtYWpvci50aWNrLmxlbmd0aCA9IDAuMiwgc2VjdG9yLmluZGV4ID0gc2VjdG9yLm5hbWUsIHRyYWNrLmluZGV4ID0gMikNCn0sIGJnLmJvcmRlciA9IE5BKQ0KDQoNCmBgYA0K